Я использую клиент Nest против Elasticsearch. Я использую анализатор индекса n-грамм. Я замечаю какое-то странное поведение - когда я ищу слова с самого начала, я не получаю никаких результатов. Однако, если я ищу со второго символа, он работает отлично. Это обычные английские буквы.
Так, например, он найдет слова, содержащие «кошечка», если я ищу «itty», «itt», «tty» и т. д., но не «ki», «kit» и т. д. Это почти как n-gram просто пропуская первый символ.
Я не уверен, вызвано ли это Nest или это нормальное поведение для n-gram. Мои настройки индекса похожи на те, что указаны в этом сообщении: Elasticsearch с использованием NEST: как настроить анализаторы для поиска неполных слов? за исключением того, что моя максимальная грамма всего 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"))
itty
вернет результаты? Можете ли вы опубликовать свое сопоставление из ES, выполнив GET /myapp/_mapping? Кроме того, если вы выполняете GET /myapp/_analyze?analyzer=custom_ngram_analyser&text=kitty, является лиkitty
токеном? Еще одна вещь: я предполагаю, что это только ваш пример, ноmyApp
не в нижнем регистре, что ES отклонит при создании индекса. - person Greg Marzouka   schedule 01.06.2014GET /myapp/_analyze?analyzer=custom_ngram_analyser&text=kitty
, иkitty
действительно появилось. - person Travis Parks   schedule 01.06.2014_mapping
. В анализаторе индекса отсутствовал фильтр токенов нижнего регистра. Небольшое исследование и код, строящий индекс, устарел. Я удалил ссылку на свой проект и снова добавил ее. Перестроен, и теперь отображается правильный фильтр токенов. Похоже, это решило и мою проблему, потому что мои старые тестовые данные включали слова со смешанным регистром. Все мои котята были написаны с большой буквы. - person Travis Parks   schedule 01.06.2014refresh
на самом деле очень полезно. Я собираюсь поиграть с большим количеством тестовых данных, поэтому мне не придется постоянно запускать тесты дважды, и это поможет мне оставаться в здравом уме. - person Travis Parks   schedule 02.06.2014nest
:) - person Martijn Laarman   schedule 03.07.2014