首页 > 解决方案 > 如何让 elasticsearch 为匹配顺序的标记字符串分配更高的分数?

问题描述

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

其他注意事项:

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

我也尝试过以下查询...(在阅读ElasticSearch 后,在匹配查询中考虑词序)它对我的问题没有帮助。

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

标签: elasticsearchn-gramrelevance

解决方案


我们可以再添加一个使用标准分析器的字段,如果查询字符串与该字段匹配,那么我们可以使用更高的值进行提升,如果不匹配,则得到 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"
            ]
        }
    }
}

推荐阅读