gpt4 book ai didi

elasticsearch - 匹配查询不返回完全匹配作为第一行

转载 作者:行者123 更新时间:2023-12-02 23:14:11 28 4
gpt4 key购买 nike

我在Elasticsearch中有数据,字段为fullName:

  • John Doe Doe
  • John Doe
  • 埃里克·约翰·道(Eric John Doe)

  • 当我针对 fullName进行匹配查询时,使用此查询
    {
    "from": 0,
    "size": 20,
    "query": {
    "bool": {
    "must": [
    {
    "match": {
    "fullName": {
    "query": "John Doe",
    "operator": "AND",
    "fuzziness": "AUTO"
    }
    }
    }
    ]
    }
    }
    }

    我希望得到 John Doe(完全匹配)作为第一个结果。
    而是,返回值按以下顺序进行:
  • John Doe Doe
  • 埃里克·约翰·道(Eric John Doe)
  • John Doe

  • 完全匹配位于最低结果上的位置。

    我应该怎么做才能将完全匹配放在第一位?
    我仍然无法对 term进行模糊匹配,因此无法使用 fullName查询

    谢谢

    最佳答案

    错误的顺序归因于2个不同的问题。

    确定第二份和第三份文件的顺序

    第二个和第三个文档之间的顺序错误可能是由于分片。如果使用单个分片,则将获得以下顺序:

  • John Doe Doe
  • John Doe
  • 埃里克·约翰·道(Eric John Doe)

  • 您可以阅读 this article,并解释原因。但是,如果每个分片中都有许多文档,则不应有此问题。如果要确保统计信息 始终正确,请在搜索查询参数中使用 _search?search_type=dfs_query_then_fetch

    确定第一份和第二份文件的顺序

    这有点棘手。如果一个词出现多次
    ,则默认的 flex 搜索相似性(即BM25)将 增加得分。在您的情况下,“母鹿”出现两次,因此其得分更高。要更改此行为,必须使用custom similarity

    您有两种解决方案:
  • 根据现有的相似性编写scripted similarity,以放弃重复术语的重要性
  • 配置默认的BM25相似度以减少重复术语的重要性

  • 要在现有索引上创建自定义相似性,您必须:
  • close the index
  • 使用_settings端点添加相似性。
  • 重新打开索引

  • 您还可以在创建索引时添加相似性。在示例中,我将始终创建一个新索引。

    要使用相似性
    ,可以将其设置为default similarity,也可以使用专门的相似性来创建子字段。请注意,更改默认相似度会影响索引中的所有查询 。在您的情况下,我认为创建子字段更好。

    解决方案1:创建脚本相似性

    使用此解决方案,您将使用脚本化相似性来丢弃重复项的影响。该脚本基于TFIDF。
    PUT /<INDEX>
    {
    "settings": {
    "index": {
    "similarity": {
    "scripted_tfidf": {
    "type": "scripted",
    "script": {
    "source": "return query.boost * (Math.log((field.docCount+1.0)/(term.docFreq+1.0)) + 1.0) / Math.sqrt(doc.length);"
    }
    }
    }
    }
    },
    "mappings": {
    "properties": {
    "fullName": {
    "type": "text",
    "fields": {
    "custom_similarity": {
    "type": "text",
    "similarity": "scripted_tfidf"
    }
    }
    }
    }
    }
    }

    评论
  • TFIDF是已弃用的相似性,但是由于其具有重复术语的行为而已弃用。由于我们消除了重复条款的影响,所以很好。
  • 因为完全丢弃了重复的术语,所以使用此解决方案时,始终始终是完全匹配,但“John Doe Doe”和“Eric John Doe”将具有相同的分数。

  • 解决方案2:配置BM25相似性

    您可以通过配置BM25 similarity来更改相似性行为。它具有2个参数k1b
  • k1:定义重复项的重要性。您想降低此值;
  • b:定义术语数量的重要性。您要增加此值。
  • PUT /<INDEX>
    {
    "settings": {
    "index": {
    "similarity": {
    "bm_25_custom": {
    "type": "BM25",

    // Update k1 and b values for bm25
    "k1": "0.1",
    "b": "1.0"
    }
    }
    }
    },
    "mappings": {
    "properties": {
    "fullName": {
    "type": "text",
    "fields": {

    // Add a subfield using the similarity defined previously
    "custom_similarity": {
    "type": "text",
    "similarity": "bm_25_custom"
    }
    }
    }
    }
    }
    }

    评论
  • 如果设置k1 = 0,则在计算分数时,重复项和项数都将被丢弃。您的第一份和第二份文档的分数相同,顺序是随机的。
  • 关于elasticsearch - 匹配查询不返回完全匹配作为第一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57193777/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com