我正在研究如何在elasticsearch中存储我的数据。首先,我尝试了模糊函数,虽然工作得很好,但我没有收到预期的结果。后来我尝试了ngram
,然后是edge_ngram
标记器。edge_ngram
标记器看起来像它的工作原理像一个自动完成。这正是我需要的。但它仍然给出了意想不到的结果。我配置了min 1
和max 5
,以获得从我搜索的第一个字母开始的所有结果。当我继续输入时,我仍然会得到这些结果。
示例:我有一个名称字段,其中包含名为The New York Times
和The Guardian
的文档。现在,当我搜索T
时,两者都如预期的那样发生。但是当我搜索TT
,TTT
等时,也会发生同样的情况。
在这种情况下,无论我是在Kibana还是在我的应用程序(在所有字段上使用MultiMatch
)中执行搜索都无关紧要。Kibana甚至向我展示了它匹配单个字母t
那么我错过了什么,我怎样才能获得像自动补全一样的结果,但没有太多的结果?
在定义索引映射时,需要指定search_analyzer
作为标准。如果没有显式定义search_analyzer
,则默认情况下elasticsearch认为search_analyzer
与指定的analyzer
相同。
添加一个包含索引数据、映射、搜索查询和搜索结果的工作示例
指数映射:
{
"settings": {
"analysis": {
"analyzer": {
"autocomplete": {
"tokenizer": "autocomplete",
"filter": [
"lowercase"
]
}
},
"tokenizer": {
"autocomplete": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 5,
"token_chars": [
"letter"
]
}
}
}
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "standard" // note this
}
}
}
}
索引数据:
{
"name":"The Guardian"
}
{
"name":"The New York Times"
}
搜索查询:
{
"query": {
"match": {
"name": "T"
}
}
}
搜索结果:
"hits": [
{
"_index": "69027911",
"_type": "_doc",
"_id": "1",
"_score": 0.23092544,
"_source": {
"name": "The New York Times"
}
},
{
"_index": "69027911",
"_type": "_doc",
"_id": "2",
"_score": 0.20824991,
"_source": {
"name": "The Guardian"
}
}
]