当前位置: 首页 > 面试题库 >

在ElasticSearch中按词条位置评分?

尉迟默
2023-03-14
问题内容

我正在ElasticSearch中实现自动完成索引,并且遇到了排序/评分问题。假设索引中包含以下字符串

apple banana coconut donut
apple banana donut durian
apple donut coconut durian
donut banana coconut durian

当我搜索“甜甜圈”时,我希望结果按术语位置来排序,如下所示:

donut banana coconut durian
apple donut coconut durian
apple banana donut durian
apple banana coconut donut

我不知道如何做到这一点。字词排名未纳入默认的评分逻辑,而且我找不到找到方法。似乎很简单,尽管以前其他人也必须遇到这个问题。有人知道吗?

谢谢!


问题答案:

根据安德烈(Andrei)的答案,这是我最终得到的解决方案,并扩展为支持多个搜索词和基于结果中第一个单词的长度的附加评分:

首先,定义以下自定义分析器(它将整个字符串保留为单个标记并将其小写):

"raw_analyzer": {
    "type": "custom",
    "filter": [
        "lowercase"
    ],
    "tokenizer": "keyword"
}

其次,像这样定义您的搜索字段映射(我的名为“ name”):

"name": {
    "type": "string",
    "analyzer": "english",
    "fields": {
        "raw": {
            "type": "string",
            "index_analyzer": "raw_analyzer",
            "search_analyzer": "standard"
        }
    }
},
"_nameFirstWordLength": {
    "type": "long"
}

第三,在填充索引时,请使用以下逻辑(在C#中为mine)填充:

_nameFirstWordLength = fi.Name.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries)[0].Length

最后,进行如下搜索:

{
   "query":{
      "bool":{
         "must":{
            "match_phrase_prefix":{
               "name":{
                  "query":"apple"
               }
            }
         },
         "should":{
            "function_score":{
               "query":{
                  "query_string":{
                     "fields":[
                        "name.raw"
                     ],
                     "query":"apple*"
                  }
               },
               "script_score":{
                  "script":"100/doc['_nameFirstWordLength'].value"
               },
               "boost_mode":"replace"
            }
         }
      }
   }
}

我正在使用match_phrase_prefix,以便支持部分匹配,例如“ ap”匹配“
apple”。布尔值必须/应该使用针对name.raw的第二个query_string查询来为名称以搜索项之一开头的结果赋予更高的分数(在我的代码中,我仅针对第二个查询对搜索字符串进行了预处理,在每个词后添加“
*”)。最后,将第二个查询包装在使用_nameFirstWordLength值的function_score脚本中,会导致第二个查询向上排序的结果按其第一个单词的长度进一步排序(例如,导致Apple在Applebee之前显示)。



 类似资料:
  • 我们有一个具有以下配置的elasticsearch索引: 结果按字段“number”进行分组,并以这种方式返回每个数字的最佳匹配。但我需要的是一个自定义的评分/排序的结果的基础上的词在结果的顺序的正确性。所以对于“乔治·布什”的质疑,“乔治·布什”应该总是比“布什·乔治”得分更高。匹配短语搜索不适合我,因为我在搜索中使用模糊性。

  • 问题内容: 我正在考虑使用Elasticsearch建立排名。如果我索引根据分数排序的元素列表。我可以按元素名称查询并获得其在索引上的位置吗? 例如我建立一个包含两个元素的索引: “ Element1”,得分:8“ Element2”,得分:7“ Element3”,得分:10 当我通过“ Element2”查询时,我想获得position = 3 问题答案: Elasticsearch在实际收集

  • 问题内容: 我有一些文档的映射,并且查询agains条件确实失败。我不明白为什么: 例如,我可以对进行词条查询,效果很好 现在 对fwot同样失败 。怎么了? 问题答案: 您需要为此工作。并且您需要为数据重新索引以使上述更改生效。 这是映射更改和一些测试数据的命令的完整列表:

  • 问题内容: 我只是编写了一个代码(使用TKinter)创建一个窗口并显示一个工作按钮。 但是我想在这个按钮下面有多个按钮。 如何设置按钮的行和列?我尝试添加,但是那行不通。 谢谢 问题答案: Astynax是正确的。要遵循您给出的示例: 应该创建3行按钮。使用网格比使用包好得多。但是,如果在一个按钮上使用网格,而在另一按钮上使用网格,则将不起作用,并且会出现错误。

  • 我的索引中有以下类型的文档,但由于深度嵌套方面,我找不到正确排序的方法。 文档示例: 我希望排序或提升在匹配时间,以便我可以得到排序的文档(asc/desc)与约束和内嵌套文档和内嵌套文档

  • 问题内容: 我正在执行类似下面的短语查询。它返回给我按相关性排序的突出显示的片段。自然,我希望用户单击一个片段,然后将文档滚动到相应的位置。但是,我在Elasticsearch中看不到任何方法来找出片段在原始文档中的位置。有任何想法吗? 问题答案: 在此期间,我们找不到合适的解决方案,并遭到了以下黑客攻击(对我们而言非常有效):在索引之前,我们用“ [index]”注释文本中的每个单词,以便“ 一