我正在对 Elasticsearch 使用 Nest 客户端。我正在使用 n-gram 索引分析器。我注意到一些奇怪的行为 - 当我从头开始搜索单词时,我没有得到任何结果。但是,如果我从第二个字符开始搜索,它会完美运行。这些只是普通的英文字母。
因此,例如,如果我搜索“itty”、“itt”、“tty”等,它会找到包含“kitty”的单词,而不是“ki”、“kit”等。这几乎就像 n-gram只是跳过第一个字符。
我不确定这是否是由 Nest 引起的,或者这是否是 n-gram 的正常行为。我的索引设置与这篇文章中的设置相似:使用 NEST 的 Elasticsearch:如何配置分析器以查找部分单词?除了我的最大克数只有 10。
更新
我稍微简化了我的代码并验证了相同的行为。
这是使用 Nest 定义的映射配置:
const string index = "myApp";
const string type = "account";
const string indexAnalyzer = "custom_ngram_analyser";
const string searchAnalyzer = "standard";
const string tokenizer = "custom_ngram_tokenizer";
const string tokenFilter = "custom_ngram_tokenFilter";
...
client.CreateIndex(index, i => i
.Analysis(ad => ad
.Analyzers(a => a.Add(indexAnalyzer, new CustomAnalyzer() { Tokenizer = tokenizer }))
.Tokenizers(t => t.Add(tokenizer, new NGramTokenizer() { MinGram = 1, MaxGram = 15 }))
.TokenFilters(f => f.Add(tokenFilter, new NgramTokenFilter() { MinGram = 1, MaxGram = 15 })))
.TypeName(account);
.IdField(r => r.SetPath("accountId").SetIndex("not_analyzed").SetStored(true));
.Properties(ps => ps.Number(p => p.Name(r => r.AccountId)
.Index(NonStringIndexOption.not_analyzed)
.Store(true));
.String(p => p.Name(r => r.AccountName)
.Index(FieldIndexOption.analyzed)
.IndexAnalyzer(indexAnalyzer)
.SearchAnalyzer(searchAnalyzer)
.Store(true)
.TermVector(TermVectorOption.no))));
这是缺少第一个字符的搜索:
SearchCriteria criteria = new SearchCriteria() { AccountName = "kitty" };
client.Search<SearchAccountResult>(s => s
.Index(index)
.Type(type)
.Query(q => q.Bool(b => b.Must(d => d.Match(m => m.OnField(r => r.AccountName).QueryString(criteria.AccountName)))))
.SortDescending("_score"))