如何让 elasticsearch 为匹配顺序的标记字符串分配更高的分数?

Posted

技术标签:

【中文标题】如何让 elasticsearch 为匹配顺序的标记字符串分配更高的分数?【英文标题】:How can I get elasticsearch to assign a higher score to strings of tokens that are in the matching order? 【发布时间】:2020-08-27 15:07:56 【问题描述】:

我正在建立一个搜索数据库。大多数条目是专有名词(名称和街道地址)。我设置了一个 ngram 令牌过滤器来帮助进行快速模糊搜索。它运作良好。但是,如果我搜索“John Allen”,结果包括具有相同分数(即相关性排名)的“John Allen”和“Allen John”。当我搜索“John Allen”时,如何调整索引设置或查询语法以使 elastic 仍然返回两个文档,但为“John Allen”分配比“Allen John”更高的分数?

这里是索引设置...

  
  "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": "3",
          "type": "ngram",
          "max_gram": "4"
        
      
    
  ,
  "mappings": 
    "properties": 
      "full_name": 
        "type": "text",
        "analyzer": "my_analyzer",
        "fields": 
          "keyword": 
            "type": "keyword"
          
        
      
    
  

这是一个示例查询...


    "query": 
        "query_string": 
            "query": "Allen John",
            "fields": [
                "full_name"
            ]
        
    

其他说明:

    我们没有使用通配符,因为它们会减慢查询速度。 我们的典型索引将包含 1000 万个文档或更少。 速度至关重要,就像在大多数弹性搜索应用程序中一样。 从我目前所读的内容来看,答案或答案的提示可能在 elasticsearch 的边缘 n-gram 标记化技术或 elasticsearch 的完成建议器中。也可能不是。

我也尝试过以下查询...(在阅读 ElasticSearch taking word order into account in match query 之后)它对我的问题没有帮助。


    "query": 
        "bool": 
            "must": 
                "query_string": 
                    "query": "Bill",
                    "fields": [
                        "full_name"
                    ]
                
            ,
            "should": 
                "span_near": 
                    "clauses": [
                        
                            "span_term": 
                                "full_name": "Bill Tim"
                            
                        
                    ],
                    "slop": 5
                
            
        
    

【问题讨论】:

【参考方案1】:

我们可以再添加一个使用标准分析器的字段,如果查询字符串与该字段匹配,那么我们可以用更高的值进行提升,如果没有,则得到 ngram 分析器匹配的分数。

"mappings": 
    "properties": 
      "full_name": 
        "type": "text",
        "analyzer": "my_analyzer",
        "fields": 
          "keyword": 
            "type": "keyword"
          ,
          "standard" :
            "type": "text" //this field uses default standard analyzer
          
        
      
    

应将搜索查询更改为包含两个字段,其中标准字段具有更高的提升值。


    "query": 
        "query_string": 
            "query": "Allen John",
            "fields": [
                "full_name", "full_name.standard^2"
            ]
        
    

【讨论】:

您确定没有遗漏任何细节吗?这没有帮助。【参考方案2】:

一个选项可以是添加另一个查询来进行短语搜索。如果词组匹配,则得分更高


  "query": 
    "bool": 
      "should": [
        
          "query_string": 
            "query": "Allen John",
            "fields": [
              "full_name"
            ]
          
        ,
        
          "query_string": 
            "query": "\"Allen John\"",
            "fields": [
              "full_name"
            ]
          
        
      ]
    
  

【讨论】:

有帮助,但这仅在查询完全匹配时才有效。如果我用一个“L”搜索“Alen John”,而不是“Allen John”,“Allen John”的得分不会比“John Allen”高

以上是关于如何让 elasticsearch 为匹配顺序的标记字符串分配更高的分数?的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch:使用 intervals query - 根据匹配项的顺序和接近度返回文档

Elasticsearch:使用 intervals query - 根据匹配项的顺序和接近度返回文档

Elasticsearch系列---近似匹配

Elasticsearch:Elasticsearch percolate 查询

Elasticsearch:Elasticsearch percolate 查询

Elasticsearch:Elasticsearch percolate 查询