当前位置: 首页 > 知识库问答 >
问题:

在elasticsearch的较早位置为包含搜索查询的匹配分配更高的分数

许黎明
2023-03-14

这个问题类似于我的另一个问题,在这里输入Val回答的链接描述。

我有一个包含3个文档的索引。

    {
            "firstname": "Anne",
            "lastname": "Borg",
        }

    {
            "firstname": "Leanne",
            "lastname": "Ray"
        },

    {
            "firstname": "Anne",
            "middlename": "M",
            "lastname": "Stone"
        }

当我搜索“Ann”时,我希望elastic返回所有这3个文档(因为它们在一定程度上都与术语“Ann”匹配)。但是,我希望符晓薇·雷具有较低的分数(相关性排名),因为搜索词“Ann”在本文档中出现的位置比该词在其他两个文档中出现的位置要晚。

这是我的索引设置…

{
    "settings": {
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "filter": [
                        "lowercase"
                    ],
                    "type": "custom",
                    "tokenizer": "my_tokenizer"
                }
            },
            "tokenizer": {
                "my_tokenizer": {
                    "token_chars": [
                        "letter",
                        "digit",
                        "custom"
                    ],
                    "custom_token_chars": "'-",
                    "min_gram": "1",
                    "type": "ngram",
                    "max_gram": "2"
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "firstname": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword"
                    }
                },
                "copy_to": [
                    "full_name"
                ]
            },
            "lastname": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword"
                    }
                },
                "copy_to": [
                    "full_name"
                ]
            },
            "middlename": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                },
                "copy_to": [
                    "full_name"
                ]
            },
            "full_name": {
                "type": "text",
                "analyzer": "my_analyzer",
                "fields": {
                    "keyword": {
                        "type": "keyword"
                    }
                }
            }
        }
    }
}

以下查询返回了预期的文档,但Leanne Ray的得分高于Anne Borg。

{
    "query": {
        "bool": {
            "must": {
                "query_string": {
                    "query": "Ann",
                    "fields": ["full_name"]
                }
            },
            "should": {
                "match": {
                    "full_name": "Ann"}
            }
        }
    }
}

以下是结果。。。

"hits": [
        {
            "_index": "contacts_4",
            "_type": "_doc",
            "_id": "2",
            "_score": 6.6333585,
            "_source": {
                "firstname": "Anne",
                "middlename": "M",
                "lastname": "Stone"
            }
        },
        {
            "_index": "contacts_4",
            "_type": "_doc",
            "_id": "1",
            "_score": 6.142234,
            "_source": {
                "firstname": "Leanne",
                "lastname": "Ray"
            }
        },
        {
            "_index": "contacts_4",
            "_type": "_doc",
            "_id": "3",
            "_score": 6.079495,
            "_source": {
                "firstname": "Anne",
                "lastname": "Borg"
            }
        }

同时使用 ngram 令牌筛选器和 ngram 令牌化器似乎可以解决此问题...

{
    "settings": {
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "filter": [
                        "ngram"
                    ],
                    "tokenizer": "ngram"
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "firstname": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword"
                    }
                },
                "copy_to": [
                    "full_name"
                ]
            },
            "lastname": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword"
                    }
                },
                "copy_to": [
                    "full_name"
                ]
            },
            "middlename": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword"
                    }
                },
                "copy_to": [
                    "full_name"
                ]
            },
            "full_name": {
                "type": "text",
                "analyzer": "my_analyzer",
                "search_analyzer": "my_analyzer"
            }
        }
    }
}

相同的查询会返回带有所需相对评分的预期结果。为什么会这样?请注意,上面,我使用的是带有小写过滤器的ngram标记器,这里唯一的区别是我使用的是ngram过滤器而不是小写过滤器。

以下是结果。请注意,根据需要,莉安·雷的得分低于安妮·博格和安妮·斯通。

"hits": [
    {
        "_index": "contacts_4",
        "_type": "_doc",
        "_id": "3",
        "_score": 4.953257,
        "_source": {
            "firstname": "Anne",
            "lastname": "Borg"
        }
    },
    {
        "_index": "contacts_4",
        "_type": "_doc",
        "_id": "2",
        "_score": 4.87168,
        "_source": {
            "firstname": "Anne",
            "middlename": "M",
            "lastname": "Stone"
        }
    },
    {
        "_index": "contacts_4",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0364896,
        "_source": {
            "firstname": "Leanne",
            "lastname": "Ray"
        }
    }

顺便说一句,当索引还包含其他文档时,此查询还会返回大量误报结果。这并不是一个问题,因为这些假阳性相对于理想点击的得分来说得分很低。但仍然不理想。例如,如果我将{firstname:Gideon,lastname:Grossma}添加到文档中,上面的查询也会将该文档返回到结果集中,尽管其分数比包含字符串“Ann”的文档低得多

共有1个答案

锺离嘉茂
2023-03-14

答案与链接线程中的答案相同。由于您正在对所有索引数据进行编码,因此它与Ann的工作方式与Anne的工作方式相同,但是,您将获得完全相同的响应(见下文),但分数不同:

"hits" : [
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "5Jr-DHIBhYuDqANwSeiw",
    "_score" : 4.8442974,
    "_source" : {
      "firstname" : "Anne",
      "lastname" : "Borg"
    }
  },
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "5pr-DHIBhYuDqANwSeiw",
    "_score" : 4.828779,
    "_source" : {
      "firstname" : "Anne",
      "middlename" : "M",
      "lastname" : "Stone"
    }
  },
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "5Zr-DHIBhYuDqANwSeiw",
    "_score" : 0.12874341,
    "_source" : {
      "firstname" : "Leanne",
      "lastname" : "Ray"
    }
  }
]

更新

下面是一个修改后的查询,您可以使用它来检查零件(即< code > ann vs < code > Anne )。同样,这里的大小写没有区别,因为分析器在索引之前会将所有内容都小写。

{
  "query": {
    "bool": {
      "must": {
        "query_string": {
          "query": "ann",
          "fields": [
            "full_name"
          ]
        }
      },
      "should": [
        {
          "match_phrase_prefix": {
            "firstname": {
              "query": "ann",
              "boost": "10"
            }
          }
        },
        {
          "match_phrase_prefix": {
            "lastname": {
              "query": "ann",
              "boost": "10"
            }
          }
        }
      ]
    }
  }
}
 类似资料:
  • 问题内容: 我正在尝试为最终用户提供搜索类型,这更像sqlserver。我能够为给定的SQL场景实现ES查询: 但是ES查询不适用于此sql查询 在我的elasticsearch以及通配符查询中,我还需要执行一些布尔过滤查询 上面的带有通配符搜索的弹性查询可以很好地工作,并让我获得所有与pete匹配且不是xyz和abc类型的文档。但是当我尝试使用以空格分隔的2个独立单词执行通配符时,相同的查询返回

  • 我有一个带有标准分析器的弹性搜索集群。我知道使用这个分析仪,术语“300”被分析为一种类型。 假设我正在搜索一个具有字段“name”的文档,该字段的值为“纸巾300 CT”,分析为[“Paper”(ALPHANUM)、“tower”(ALPHANUM)、“300”(NUM)、“CT”(ALPHANUM)] 目前,当我使用模糊/通配符查询时,如下所示: 无论模糊性如何调整,模糊查询都不匹配。我希望术

  • 我正在对elasticsearch(1.7)进行常规搜索,使用对许多指定字段的匹配查询。这是在一个java应用程序中完成的,只有一个框可以输入搜索项。允许各种搜索选项(例如,用引号包围短语来查找阶段,而不是成分词)。这意味着我正在进行全面的测试搜索。 一切都很好,除了我的帐户裁判有正斜杠在他们和一个帐户裁判的搜索产生成千上万的结果。如果我用引号包围帐户引用,我就得到了我想要的结果。我假设AC/12

  • 假设我有一些文档,在名为“名称”的文本字段中包含以下值 文档1: 文档2: 文档3: 现在,假设我向ES发送一个简单的匹配查询,查询术语“组”: 我期望的结果是,无论术语出现的频率、出现的位置等,所有3个文档都会以相同的分数返回。现在,我已经知道,我可以通过将我的匹配项包装为常量分数来实现这一点,如下所示: 但是,假设我现在想使用搜索词abc组进行查询。在这种情况下,我希望Document2和Do

  • 问题内容: 使用GAE搜索API是否可以搜索部分匹配项? 我正在尝试创建自动完成功能,其中该术语将是部分单词。例如。 b bui 构建 都将返回“建筑物”。 GAE怎么可能? 问题答案: 尽管全文搜索不支持LIKE语句(部分匹配),但是您可以修改它。 首先,为所有可能的子字符串标记数据字符串(hello = h,he,hel,lo等) 使用标记化的字符串构建索引+文档(搜索API) 执行搜索,然后

  • 匹配查询用于实现以下情况的映射是什么 不区分大小写的搜索 数字搜索 特殊字符搜索 单字符搜索 > 我尝试使用通配符,但id不支持区分大小写 尝试使用小写规范化器匹配查询,它不支持特殊字符和单字符搜索 已尝试使用 ngram 匹配查询,但它不支持特殊字符和数字搜索。 任何人都可以帮助我的映射来支持上面提到的所有情况,无论是类型还是类型都很好