0

我正在尝试编写一个 Elasticsearch 多重匹配查询(使用 Java API)来创建一个“搜索即输入”程序。该查询应用于两个字段titledescription,它们被分析为 ngram。

我的问题是,Elasticsearch 似乎只尝试查找以我的查询开头的单词。例如,如果我搜索“nut”,则它与具有“ nut ”、“ nuts ”、“ Nutella ”等特征的文档匹配,但它不匹配具有“ walnut ”特征的文档,应该匹配。

这是我的设置:

{
    "index": {
        "analysis": {
            "analyzer": {
                "edgeNGramAnalyzer": {
                    "tokenizer": "edgeTokenizer",
                    "filter": [
                        "word_delimiter",
                        "lowercase",
                        "unique"
                    ]
                }
            },
            "tokenizer": {
                "edgeTokenizer": {
                  "type": "edgeNGram",
                  "min_gram": "3",
                  "max_gram": "8",
                  "token_chars": [
                    "letter",
                    "digit"
                  ]
                }
            }
        }
    }
}

这是我的映射的相关部分:

{
    "content": {
        "properties": {
            "title": {
                "type": "text",
                "analyzer": "edgeNGramAnalyzer",
                "fields": {
                    "sort": { 
                        "type": "keyword"
                    }
                }
            },
            "description": {
                "type": "text",
                "analyzer": "edgeNGramAnalyzer",
                "fields": {
                    "sort": { 
                        "type": "keyword"
                    }
                }
            }
        }
    }
}

这是我的查询:

new MultiMatchQueryBuilder(query).field("title", 3).field("description", 1).fuzziness(0).tieBreaker(1).minimumShouldMatch("100%")

你知道我做错了什么吗?

4

1 回答 1

1

那是因为您使用的是edgeNGram分词器而不是分词器nGram。前者仅索引前缀,而后者将索引前缀、后缀以及数据的子部分。

将您的分析器定义改为此,它应该按预期工作:

{
    "index": {
        "analysis": {
            "analyzer": {
                "edgeNGramAnalyzer": {
                    "tokenizer": "edgeTokenizer",
                    "filter": [
                        "word_delimiter",
                        "lowercase",
                        "unique"
                    ]
                }
            },
            "tokenizer": {
                "edgeTokenizer": {
                  "type": "nGram",         <---- change this
                  "min_gram": "3",
                  "max_gram": "8",
                  "token_chars": [
                    "letter",
                    "digit"
                  ]
                }
            }
        }
    }
}
于 2017-07-19T11:55:35.143 回答