ElasticSearch:精确得分低于部分匹配

时间:2016-03-09 10:25:34

标签: json elasticsearch autocomplete

我正在尝试使用ElasticSearch实现地址自动填充。

假设我有三个字段,我想在其中实现搜索:

{
    "address_name": "George st.",
    "number": "1",
    "city_name": "London"
}

根据this article,我已经配置了我的索引并输入如下:

{
    "settings": {
        "analysis": {
            "filter": {
                "nGram_filter": {
                    "type": "nGram",
                    "min_gram": 1,
                    "max_gram": 20,
                    "token_chars": [
                        "letter",
                        "digit",
                        "punctuation",
                        "symbol"
                    ]
                }
            },
            "analyzer": {
                "nGram_analyzer": {
                    "type": "custom",
                    "tokenizer": "whitespace",
                    "filter": [
                        "lowercase",
                        "asciifolding",
                        "nGram_filter"
                    ]
                },
                "whitespace_analyzer": {
                    "type": "custom",
                    "tokenizer": "whitespace",
                    "filter": [
                        "lowercase",
                        "asciifolding"
                    ]
                }
            }
        }
    },
    "mappings": {
        "address": {
            "_all": {
                "analyzer": "nGram_analyzer",
                "search_analyzer": "whitespace_analyzer"
            },
            "properties": {
                "address_name": {
                    "type": "string"
                },
                "number": {
                    "type": "string",
                    "boost": 2
                },
                "city_name": {
                    "type": "string"
                },
                "local": {
                    "type": "integer",
                    "include_in_all": false,
                    "index": "no"
                },
                "place_id": {
                    "type": "integer",
                    "include_in_all": false,
                    "index": "no"
                },
                "has_number": {
                    "type": "integer",
                    "include_in_all": false,
                    "index": "no"
                }
            }
        }
    }
}

完整搜索查询:

{
    "size": 100,
    "query": {
        "match": {
            "_all": {
                "query": "George st. 1 London",
                "operator": "and"
            }
        }
    }
}

当我按查询George st. 1 London搜索时,ElasticSearch首先返回George st. 19 LondonGeorge st. 17 London等,但完全匹配George st. 1 London仅在第X位返回得分低于第一名。

我试图通过在搜索网址的末尾添加explain查询来了解其原因,但它没有帮助。

有什么方法可以解决这个问题吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

基本上,由于您在索引时通过nGram令牌过滤器运行所有字段,这意味着对于number字段,

  • 17将被标记为117以及
  • 19将被标记为119

因此,您提及的所有三个文档都会为其1字段编制索引标记number

然后在查询时,您正在使用空白分析器,这意味着George st. 1 London将被标记为以下令牌:Georgest,{{1} }和1

从那里,我们可以得出两个结论:

  1. 所有三个文件无论如何都会匹配(因为所有标记都与给定字段匹配)
  2. 目前的设置和映射无法让您对文档London给予更多权重而不是其他文档。
  3. 最简单的方法是不将nGram应用于数字字段,以便街道号码需要精确匹配,而不是前缀。