Elasticsearch — Nest — отсутствует первый символ

Я использую клиент 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"))

person Travis Parks    schedule 31.05.2014    source источник
comment
Привет, Трэвис Паркс, не мог бы ты опубликовать свою карту и поисковый запрос?   -  person Greg Marzouka    schedule 31.05.2014
comment
@Greg Marzouka Я обновил свой вопрос.   -  person Travis Parks    schedule 01.06.2014
comment
хм, кажется, работает нормально для меня. Просто чтобы уточнить, с тем же кодом выше itty вернет результаты? Можете ли вы опубликовать свое сопоставление из ES, выполнив GET /myapp/_mapping? Кроме того, если вы выполняете GET /myapp/_analyze?analyzer=custom_ngram_analyser&text=kitty, является ли kitty токеном? Еще одна вещь: я предполагаю, что это только ваш пример, но myApp не в нижнем регистре, что ES отклонит при создании индекса.   -  person Greg Marzouka    schedule 01.06.2014
comment
Itty возвращает результаты.   -  person Travis Parks    schedule 01.06.2014
comment
Я запустил GET /myapp/_analyze?analyzer=custom_ngram_analyser&text=kitty, и kitty действительно появилось.   -  person Travis Parks    schedule 01.06.2014
comment
Я пошел за своим текущим _mapping. В анализаторе индекса отсутствовал фильтр токенов нижнего регистра. Небольшое исследование и код, строящий индекс, устарел. Я удалил ссылку на свой проект и снова добавил ее. Перестроен, и теперь отображается правильный фильтр токенов. Похоже, это решило и мою проблему, потому что мои старые тестовые данные включали слова со смешанным регистром. Все мои котята были написаны с большой буквы.   -  person Travis Parks    schedule 01.06.2014
comment
Я также заметил, что если я построил свои тестовые данные и сразу же запросил данные, я не получил никаких результатов. Я увижу результат только со второго раза. Я предполагаю, что существует задержка между добавлением/индексированием данных и их отображением. Я не думал, что ответ был возвращен до тех пор, пока значение не было проиндексировано и реплицировано... не думаю.   -  person Travis Parks    schedule 01.06.2014
comment
Привет, @Travis Parks, рад, что ты разобрался с проблемой. К сведению: документы недоступны для поиска после индексации до обновление. Это может происходить в вашем индексе с определенным интервалом (по умолчанию — каждую 1 секунду), но вы также можете вручную выполнить обновление с некоторыми небольшими последствиями для производительности. Однако вы можете получить документ сразу после индексации с помощью get API.   -  person Greg Marzouka    schedule 02.06.2014
comment
@GregMarzouka Знание о refresh на самом деле очень полезно. Я собираюсь поиграть с большим количеством тестовых данных, поэтому мне не придется постоянно запускать тесты дважды, и это поможет мне оставаться в здравом уме.   -  person Travis Parks    schedule 02.06.2014
comment
@TravisParks не могли бы ответить на свой вопрос? Мы хотели бы, чтобы процент отвеченных оставался на теге nest :)   -  person Martijn Laarman    schedule 03.07.2014


Ответы (1)


Я столкнулся с этой проблемой, потому что изначально мой индекс был чувствителен к регистру. Все мои тестовые данные начинались с заглавных букв.

Я изменил его на нечувствительный к регистру, но обновление произошло не сразу. Несмотря на то, что анализатор был настроен как нечувствительный к регистру, индекс не обновлялся.

Удаление индекса и его повторное заполнение с нуля устранило проблему.

person Travis Parks    schedule 11.03.2015