小编典典

使用NEST的Elasticsearch:如何配置分析器以查找部分单词?

elasticsearch

我试图通过部分单词进行搜索,而忽略大小写并忽略某些字母的重音。可能吗?我认为使用默认标记器的ngram应该可以解决问题,但我不知道如何使用NEST来实现。

示例:“音乐”应匹配具有“音乐”的记录

我使用的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);

谢谢,

大卫


阅读 348

收藏
2020-06-22

共1个答案

小编典典

简短答案

我认为您正在寻找的是模糊查询,该查询使用Levenshtein距离算法来匹配相似的单词。

关于nGrams的长答案

nGram过滤器根据定义的最小/最大范围将文本分成许多较小的标记。

例如,根据您的“音乐”查询,过滤器将生成: 'mu', 'us', 'si', 'ic', 'mus', 'usi', 'sic', 'musi', 'usic', and 'music'

如您所见musiic,与这些nGram令牌都不匹配。

为什么选择nGrams

nGrams的一个好处是,它可以 大大
加快通配符查询的速度,因为所有潜在的子字符串都是在插入时预先生成和索引的(我已经看到使用nGrams可以将查询速度从几秒提高到15毫秒)。

如果没有nGrams,则必须在查询时在每个字符串中搜索匹配项[O(n ^ 2)],而不是直接在索引[O(1)]中查找。作为伪代码:

hits = []
foreach string in index:
    if string.substring(query):
        hits.add(string)
return hits

return index[query]

请注意,这样做的代价是使插入速度变慢,需要更多的存储空间并增加了内存使用量。

2020-06-22