Статьи

Советы по поиску имени в Solr

Поиск имен является довольно распространенным требованием для многих приложений. Например, поиск по авторам книг — очень важный компонент книжного магазина. И, как выясняется, имена на самом деле удивительно сложно сделать идеальным . Несмотря на это, мы можем получить что-то довольно хорошее, работая в Solr, по крайней мере, для подавляющего большинства представлений на английском языке.

векторы весело

Помните старые добрые времена «Альфы автора»?

Мы можем начать с предположения, что помимо всего многообразия человеческих имен, что имя в нашем поле Авторы, скорее всего, будет небольшой горсткой токенов в одном поле. Мы не будем разбивать эти имена на имена, фамилии и отчества (если они даже подходят во всех культурных контекстах). Давайте начнем с рассмотрения некоторых примеров имен в нашем поле «Авторы»:

Авторы:

  • Тернбулл, Дуглас
  • Тернбулл, Дуглас Г.
  • Тернбулл, Д.Г.
  • Д. Грэм Тернбулл

Хорошо, вы уже можете видеть различия в том, как мы представляем англичизированные имена. Это позволяет нам строить нашу стратегию. Во-первых, для записи, мы собираемся использовать эту довольно простую цепочку анализа для нашей области авторов. Это сделает работу по удалению знаков препинания и строчных букв:

<fieldType name="AuthorsType" class="solr.TextField"  positionIncrementGap="100">       
  <analyzer>
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory" />
  </analyzer>
</fieldType>

ОК, до дела. Есть две основные проблемы, которые, если бы мы могли решить, могли бы решить очень большую часть проблемы поиска имен

  1. Имена авторов переупорядочиваются либо в документе, либо в запросе, с некоторыми пропущенными частями: (Дуглас Тернбулл против Тернбулла, Дуглас против Тернбулла Дуглас G)

Переставленные имена

Изменение порядка жетонов автора — довольно простое упражнение в использовании поиска близости Lucene. Эта особенность синтаксиса запроса Lucene позволяет нам принимать запрос пользователя и бесконтактный P:

  • Дуглас Тернбулл

И искать фразы, которые являются фразой, введенной пользователем, или фразы, где термины встречаются в пределах P-близости друг к другу. Итак, выражая это в синтаксисе запроса Lucene:

  • Авторы: ”Дуглас Тернбулл” ~ 2

С радостью выдаст результаты, в которых Дуглас и Тернбулл встречаются в течение двух ходов жетонов друг от друга (независимо от порядка). Следующие совпадения будут приемлемы:

  • Дуглас Тернбулл
  • Тернбулл Дуглас

Учитывая средние инициалы, мы могли бы установить нашу близость к 3, поэтому запрос для:

  • Авторы: «Дуглас Тернбулл» ~ 3

Теперь будет соответствовать:

  • Дуглас Дж. Тернбулл
  • Тернбулл, Дуглас Г.

Отлично, мы решили эту проблему! Ну, на самом деле, это работает в большинстве, но не во всех случаях. Можете ли вы обнаружить тонкую ошибку? Вот подсказка: это связано с использованием запроса фразы. Есть ли класс запросов, для которых эта стратегия не будет работать?

Инициалы и короткие формы

Что происходит, когда пользователь ищет Дуга Тернбулла и все, что Солр проиндексировал, являются ссылками на Дугласа Тернбулла? Чтобы помочь с эффективными префиксными запросами, Solr предоставляет нам EdgeNGramFilterFactory. EdgeNGramFilterFactory берет токен, скажем, Дуглас, и генерирует токены, основанные на разрезании строки либо спереди, либо сзади строки. Например, при minGramSize = 1 и side = «front» токен «Douglas» приведет к следующим токенам:

Input:  douglas
Tokens: [d] [do] [dou] [doug] [dougl] [dougla] [douglas]

Важное замечание об этом фильтре (и многих других в Solr) заключается в том, что каждый сгенерированный токен занимает одну и ту же позицию в проиндексированном документе. В действительности, мы можем представить документ как двухмерный:

Position N:     Position N+1
    [d]         ->  [t]
    [do]            [tu]
    ...             ...
    [douglas]       [turnbull]

Таким образом, запрос фразы «do turnbull» будет применен к этому документу в том же месте в этом документе, что и фраза «douglas turnbull». Какая замечательная характеристика! Итак, мы сможем сопоставить сокращенное «D. Turnbull» просто используя этот фильтр в нашей цепочке анализа следующим образом:

поле:

<field name="AuthorsPre" type="AuthorsPrefix" indexed="true" multiValued="true"/>

Копировать поле:

<copyField source="Authors" dest="AuthorsPre"/>

Тип поля:

<fieldType name="AuthorsPrefix" class="solr.TextField"  positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory" />
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="200" side="front"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory" />
  </analyzer>
</fieldType>

Давайте пройдем эту цепочку анализа через пример запроса в поле AuthorsPre, чтобы увидеть, как он работает. Имя «Дуглас Дж. Тернбулл» индексируется следующим образом:

Position            N           N+1     N+2
Standard Tokenizer: [Douglas]   [G]     [Turnbull]
Lower Case Filter:  [douglas]   [G]     [turnbull]
NGram Filter:       [d]         [g]     [t]
                    [do]                [tu]
                    …(etc)…             …(etc)…
                    [douglas]           [turnbull]

Теперь давайте возьмем запрос пользователя: «DG Turnbull». Это довольно просто использовать для анализа цепочки запросов в [d] [g] [turnbull]. Эти токены встречаются в индексе везде, где было проиндексировано имя Дуглас Дж. Тернбулл (а также там, где был индексирован Дэвид Дж. Тернбулл)!

Положить его вместе

ОК, настало время активизировать свою игру. Теперь пользователь вошел в «Turnbull, D.» в поле поиска. Что теперь? Ну, мы просто применяем тот же трюк, который использовали ранее. Вместо того чтобы искать:

  • AuthorsPre: ”Тернбулл, Д.”

Давайте превратим это в запрос близости:

  • AuthorsPre: ”Turnbull D.” ~ 3

Есть много кусочков знаний, объединенных сразу, чтобы увидеть, как это работает. Во-первых, как мы уже говорили, все сгенерированные ngrammed токены занимают одинаковую позицию в потоке токенов. Таким образом, [D.] и [Douglas] находятся в одной позиции в проиндексированном документе. Это означает, что когда позиция имеет значение (как в запросе фразы) «D. Тернбулл »и« Дуглас Тернбулл »оба будут соответствовать документу, содержащему« Дуглас Тернбулл ». Наш поиск близости, с другой стороны, дает Solr некоторую свободу немного переставлять токены, чтобы удовлетворить соответствие, предоставляя немного свободы в расположении имен, что приводит к совпадению во многих переставленных и сокращенных формах нашего имени.

Это только начало

Это довольно хорошее начало, но поиск — это эвристика, которую всегда можно улучшить. Осталось еще много работы, чтобы сделать это идеальным! Помимо многочисленных противоречивых культурных соглашений, которые, я уверен, я нарушил, читателю предлагается множество упражнений:

векторы весело

Приходите на тренировку Solr и поставьте эту болванку вместе с решениями этих проблем!

  • Как вы предпочитаете точные совпадения по сравнению с префиксными именами?
  • Как вы могли бы определить, какие маркеры запросов предназначены для отчеств, фамилий, фамилий и фамилий?
  • Стандартный токенизатор разбивает дефисные имена, как вы можете сохранить дефисное имя как один токен?
  • Многие сокращения имени не просто префиксы оригинального имени. Например, как бы вы сопоставили «Томас», когда пользователь вводит «Том»?

Итак, есть несколько забавных головоломок, чтобы улучшить вашу игру Solr! И если вы действительно хотите улучшить свою игру Solr по этим и другим проблемам, обязательно ознакомьтесь с нашей Solr Training !

Поделитесь своими мыслями! Надеюсь, эта статья поможет вам начать поиск разумного имени. У вас были проблемы с поиском имени в прошлом? Как вы подошли к этим проблемам с Solr? И, конечно же, свяжитесь с нами для решения проблем поиска вашего имени!