我试图通过部分单词进行搜索,忽略套管并忽略某些字母的加重。可能吗?我认为ngram与默认的tokenizer应该做的伎俩,但我不明白如何使用NEST。
示例:“musiic”应匹配具有“music”
的记录我使用的Elasticsearch版本是1.9。
我这样做但它不起作用......
var ix = new IndexSettings();
ix.Add("analysis",
@"{
'index_analyzer' : {
'my_index_analyzer' : {
'type' : 'custom',
'tokenizer' : 'standard',
'filter' : ['lowercase', 'mynGram']
}
},
'search_analyzer' : {
'my_search_analyzer' : {
'type' : 'custom',
'tokenizer' : 'standard',
'filter' : ['standard', 'lowercase', 'mynGram']
}
},
'filter' : {
'mynGram' : {
'type' : 'nGram',
'min_gram' : 2,
'max_gram' : 50
}
}
}");
client.CreateIndex("sample", ix);
谢谢,
大卫
答案 0 :(得分:2)
简答
我认为您正在寻找的是fuzzy query,它使用Levenshtein distance算法匹配相似的字词。
关于nGrams的长答案
nGram过滤器根据定义的最小/最大范围将文本拆分为许多较小的标记。
例如,来自您的音乐'查询过滤器将生成:
'mu', 'us', 'si', 'ic', 'mus', 'usi', 'sic', 'musi', 'usic', and 'music'
正如您所看到的,musiic
与这些nGram令牌中的任何一个都不匹配。
为什么nGrams
nGrams的一个好处是它使得通配符查询显着更快,因为所有潜在的子串都是在插入时预生成和索引的(我已经看到查询从几秒加速到15毫秒使用n元语法)。
如果没有nGrams,必须在查询时搜索每个字符串以匹配[O(n ^ 2)],而不是直接在索引[O(1)]中查找。作为伪代码:
hits = []
foreach string in index:
if string.substring(query):
hits.add(string)
return hits
VS
return index[query]
请注意,这是以降低插入速度,需要更多存储空间和更大内存使用为代价的。