gpt4 book ai didi

elasticsearch - 在 Elasticsearch 中正确排序完全匹配和 "beginning with"(前缀)

转载 作者:行者123 更新时间:2023-12-02 22:48:12 26 4
gpt4 key购买 nike

我需要使用 Elasticsearch 改进搜索结果列表。

假设我们有 3 个具有单个字段和内容的文档,如下所示:

  • “苹果”
  • 《青苹果》
  • 《苹果树》

  • 如果我搜索“苹果”,可能会得到这样排序的结果:
  • 《青苹果》
  • 《苹果树》
  • “苹果”

  • 但我想要的是获得最高分的完全匹配,这里是带有“apple”的文档。

    下一个最高分应该是以搜索词开头的条目,这里是“苹果树”,其余排序默认方式。

    所以我想拥有它:
  • “苹果”
  • 《苹果树》
  • 《青苹果》

  • 我试图通过使用 rescore 来实现它:
    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 似乎用空格分隔所有单词。例如,搜索“apple*”也将提供“green apple”。这似乎是重新评分对我不起作用的原因。

    可能还有其他字符,例如点“.”、“-”、“;” Elasticsearch 用于拆分和打乱我的排序等。

    我还在“rescore_query”中使用“match_phrase”而不是“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_field1whitespace分析器以确保通过使用空格作为唯一分隔符来创建标记。其次,我创建了一个名为 keyword 的子字段。类型 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。
    POST test/_doc/_search
    {
    "explain": true,
    "query": {
    "query_string": {
    "query": "apple",
    "fields": [
    "my_field1"
    ]
    }
    }
    }
    "explain": true在上面的查询中给出输出中的分数计算步骤。阅读本文将使您了解文档的评分方式。

    我们需要做的就是提高精确匹配的分数。我们将对字段 my_field1.keyword 进行精确匹配.您可能有一个问题,为什么不 my_field1 .原因是因为 my_field1经分析,当为3个文档的输入字符串生成token时,都会有一个token(term) apple (连同其他术语,如果存在,例如 tree 用于文档 2 和 green 用于文档 3)针对该字段存储。当我们在该字段上对 apple 进行精确匹配时所有文档都将匹配并对每个文档的分数产生类似的影响,因此分数没有变化。由于只有一个文档具有精确值 apple反对 my_field1.keyword该文档(doc 1)将与精确查询匹配,我们将对此进行改进。所以查询将是:
    {
    "query": {
    "bool": {
    "should": [
    {
    "query_string": {
    "query": "apple",
    "fields": [
    "my_field1"
    ]
    }
    },
    {
    "query_string": {
    "query": "\"apple\"",
    "fields": [
    "my_field1.keyword^2"
    ]
    }
    }
    ]
    }
    }
    }

    上述查询的输出:
    {
    "took": 9,
    "timed_out": false,
    "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
    },
    "hits": {
    "total": 3,
    "max_score": 1.7260925,
    "hits": [
    {
    "_index": "test3",
    "_type": "_doc",
    "_id": "1",
    "_score": 1.7260925,
    "_source": {
    "my_field1": "apple"
    }
    },
    {
    "_index": "test3",
    "_type": "_doc",
    "_id": "2",
    "_score": 0.6931472,
    "_source": {
    "my_field1": "apple tree"
    }
    },
    {
    "_index": "test3",
    "_type": "_doc",
    "_id": "3",
    "_score": 0.2876821,
    "_source": {
    "my_field1": "green apple"
    }
    }
    ]
    }
    }

    关于elasticsearch - 在 Elasticsearch 中正确排序完全匹配和 "beginning with"(前缀),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54532813/

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