elasticsearch Elasticsearch中精确匹配和“以开头”(前缀)的正确排序
我需要用Elasticsearch改进搜索结果列表 假设我们有3个文档,其中只有一个字段,内容如下: 苹果 青苹果 苹果树 如果我搜索苹果,我可能会得到如下排序结果: 青苹果 苹果树 苹果 但我想要的是精确匹配的最高分数,这里是与苹果的文档 下一个最高分应该是以搜索词开头的条目,这里是苹果树,其余按默认方式排序 所以我想让它这样: 苹果 苹果树 青苹果 我已尝试通过使用rescore实现此目标:
elasticsearch Elasticsearch中精确匹配和“以开头”(前缀)的正确排序,
elasticsearch,
elasticsearch,我需要用Elasticsearch改进搜索结果列表 假设我们有3个文档,其中只有一个字段,内容如下: 苹果 青苹果 苹果树 如果我搜索苹果,我可能会得到如下排序结果: 青苹果 苹果树 苹果 但我想要的是精确匹配的最高分数,这里是与苹果的文档 下一个最高分应该是以搜索词开头的条目,这里是苹果树,其余按默认方式排序 所以我想让它这样: 苹果 苹果树 青苹果 我已尝试通过使用rescore实现此目标: curl -X GET "http://localhost:9200/my_index_name/_
curl -X GET "http://localhost:9200/my_index_name/_search?size=10&pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"query_string": {
"query": "apple"
}
},
"rescore": {
"window_size": 500,
"query": {
"score_mode": "multiply",
"rescore_query": {
"bool": {
"should": [
{
"match": {
"my_field1": {
"query": "apple",
"boost": 4
}
}
},
{
"match": {
"my_field1": {
"query": "apple*",
"boost": 2
}
}
}
]
}
},
"query_weight": 0.7,
"rescore_query_weight": 1.2
}
}
}'
但这并没有真正起作用,因为Elasticsearch似乎用空格分隔所有单词。例如,搜索苹果*也将提供绿色苹果。这似乎就是rescore不为我工作的原因
可能还有点等其他字符;等。Elasticsearch将其用于拆分并扰乱我的排序
我还在rescore_查询中使用match_短语代替bool,但没有成功
我也尝试过仅使用一种匹配:
curl -X GET "http://localhost:9200/my_index_name/_search?size=10&pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"query_string": {
"query": "apple"
}
},
"rescore": {
"window_size": 500,
"query": {
"score_mode": "multiply",
"rescore_query": {
"bool": {
"should": [
{
"match": {
"my_field1": {
"query": "apple*",
"boost": 2
}
}
}
]
}
},
"query_weight": 0.7,
"rescore_query_weight": 1.2
}
}
}'
这似乎有效,但我还是不确定。这是正确的方法吗
EDIT1:对于其他查询,一个匹配的重新排序不正确。唯一需要在分数中进行操作的地方是精确匹配,否则术语的位置顺序会给出正确的顺序。让我们通过以下内容来理解这一点: 让我们首先创建一个映射,如下所示:
PUT test
{
"mappings": {
"_doc": {
"properties": {
"my_field1": {
"type": "text",
"analyzer": "whitespace",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
}
我使用空白分析器创建了字段my_field1,以确保令牌是通过使用空格作为唯一的分隔符来创建的。其次,我创建了一个子字段,名为keyword类型的keyword。关键字将保存输入字符串的未分析值,我们将使用它进行精确匹配
让我们向索引中添加几个文档:
PUT test/_doc/1
{
"my_field1": "apple"
}
PUT test/_doc/2
{
"my_field1": "apple tree"
}
PUT test/_doc/3
{
"my_field1": "green apple"
}
如果使用下面的查询搜索术语apple,文档的顺序将是
2,1,3
解释:在上述查询中为true,在输出中给出分数计算步骤。阅读本文将使您了解文档是如何评分的
我们所需要做的就是,为精确的比赛提高分数。我们将对字段my_field1.keyword进行精确匹配。你可能会有一个问题,为什么不是我的。这是因为对my_field1进行了分析,当为3个文档的输入字符串生成标记时,所有标记都将包含一个标记术语apple以及其他术语(如果存在),例如文档2的树和文档3的绿色,存储在该字段中。当我们为术语apple在该字段上运行“精确匹配”时,所有文档都将匹配,并且对每个文档的分数有类似的影响,因此分数没有变化。由于只有一个文档与my_field1.keyword相比具有与apple相同的精确值,因此文档doc 1将与精确查询匹配,我们将对此进行改进。因此,查询将是:
{
"query": {
"bool": {
"should": [
{
"query_string": {
"query": "apple",
"fields": [
"my_field1"
]
}
},
{
"query_string": {
"query": "\"apple\"",
"fields": [
"my_field1.keyword^2"
]
}
}
]
}
}
}
上述查询的输出:
唯一需要操纵分数的地方是精确匹配,否则术语的位置顺序会给出正确的顺序。让我们通过以下内容来理解这一点: 让我们首先创建一个映射,如下所示:
PUT test
{
"mappings": {
"_doc": {
"properties": {
"my_field1": {
"type": "text",
"analyzer": "whitespace",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
}
我使用空白分析器创建了字段my_field1,以确保令牌是通过使用空格作为唯一的分隔符来创建的。其次,我创建了一个子字段,名为keyword类型的keyword。关键字将保存输入字符串的未分析值,我们将使用它进行精确匹配
让我们向索引中添加几个文档:
PUT test/_doc/1
{
"my_field1": "apple"
}
PUT test/_doc/2
{
"my_field1": "apple tree"
}
PUT test/_doc/3
{
"my_field1": "green apple"
}
如果使用下面的查询搜索术语apple,文档的顺序将是
2,1,3
解释:在上述查询中为true,在输出中给出分数计算步骤。阅读本文将使您了解文档是如何评分的
我们所需要做的就是,为精确的比赛提高分数。我们将对字段my_field1.keyword进行精确匹配。你可能会有一个问题,为什么不是我的。这是因为对my_field1进行了分析,当为3个文档的输入字符串生成标记时,所有标记都将包含一个标记术语apple以及其他术语(如果存在),例如文档2的树和文档3的绿色,存储在该字段中。当我们为术语apple在该字段上运行“精确匹配”时,所有文档都将匹配,并且对每个文档的分数有类似的影响,因此分数没有变化。由于只有一个文档与my_field1.keyword相比具有与apple相同的精确值,因此文档doc 1将与精确查询匹配,我们将对此进行改进。因此,查询将是:
{
"query": {
"bool": {
"should": [
{
"query_string": {
"query": "apple",
"fields": [
"my_field1"
]
}
},
{
"query_string": {
"query": "\"apple\"",
"fields": [
"my_field1.keyword^2"
]
}
}
]
}
}
}
上述查询的输出:
Nishant Saini感谢您的回复。您是否只考虑精确匹配或使用关键字类型嵌套字段,还确保以单词/短语开头会更高?例如,如果我们使用您建议的查询搜索苹果,则苹果树的得分总是高于绿苹果?这只适用于精确匹配。弹性不得分的基础上的立场。为此,您需要编写自己的cu
斯托姆逻辑。为了编写自定义逻辑/插件,我测试了您的建议并接受了您的回答,即使我不确定它是否能满足前缀要求,但至少在我的示例中,它工作得非常完美。谢谢:对于前缀,我建议使用或标记器来定制analyzer。然后使用or.Nishant Saini感谢您的回复。您是否只考虑精确匹配或使用关键字类型嵌套字段,还确保以单词/短语开头会更高?例如,如果我们使用您建议的查询搜索苹果,则苹果树的得分总是高于绿苹果?这只适用于精确匹配。弹性不得分的基础上的立场。为此,您需要编写自己的自定义逻辑。为了编写自定义逻辑/插件,我测试了您的建议并接受了您的回答,即使我不确定它是否能满足前缀要求,但至少在我的示例中,它工作得非常完美。谢谢:对于前缀,我建议使用或标记器来定制analyzer。然后使用or。