Фразы для поиска по близости с помощью корневых расширителей в Solr или ElasticSearch (особенно websolr или bonsai.io)?

Я пытаюсь выбрать инструмент поиска для большого проекта, и мне было бы интересно узнать, поддерживается ли этот вариант использования Solr или ElasticSearch.

Мои клиенты заинтересованы в проведении относительно сложного логического поиска. Одним из обязательных условий поиска является возможность проводить поиск близости по фразам с корневыми расширителями.

Например, представьте, что пользователь ищет документ с такой фразой: «На милую собаку напали злые еноты».

Я хочу, чтобы пользователь мог искать «evil rac*» в пределах 5 слов от «собаки» и возвращать документ с приведенным выше предложением. В идеале запрос должен выглядеть примерно так:

("злая раса*" собака)~5

До сих пор единственным найденным мной инструментом поиска, который может делать то, что я ищу, является dtSearch. Запрос для dtSearch будет «evil rac*» с 5 собаками, и это здорово. Я бы предпочел использовать инструмент с открытым исходным кодом, такой как Solr или ElasticSearch (и особенно размещенное решение, такое как websolr или bonsai.io). Любые советы будут очень признательны.


person Jake    schedule 08.04.2013    source источник
comment
Эй, Джейк, тут Ник с websolr/bonsai. У вас есть еще примеры запросов, которые вы пробовали, и их результирующее поведение? Я подозреваю, что цитирование капель или иным образом трактует звездочку буквально.   -  person Nick Zadrozny    schedule 08.04.2013


Ответы (3)


Определенно технически возможно, но пока не поддерживается в Lucene. Есть несколько открытых проблем для поддержки поведения «сложной фразы» в Lucene, которое, по-видимому, нацелено на Lucene 4.3:

LUCENE-1486 — расширение стандартного QueryParser, которое переопределяет синтаксический анализ фразовых запросов для разрешить более сложный синтаксис, например подстановочные знаки во фразовых запросах.

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

Напомним: теоретически возможно, не поддерживается в синтаксисе по состоянию на апрель 2013 г. и Lucene 4.2.1.

(Спасибо моему деловому партнеру Кайлу за помощь в исследовании.)

person Nick Zadrozny    schedule 08.04.2013

Технически это, безусловно, возможно сделать с помощью пользовательского анализатора запросов, но парсеры по умолчанию, dismax и т. д. в solr, похоже, не поддерживают это. Об этом есть старая и нерешенная проблема: https://issues.apache.org/jira/browse/SOLR-1604.

ElasticSearch будет поддерживать это только с построителем запросов JSON, но похоже, что поддержка фразоподобных запросов предназначена только для «span_term», которые являются просто словами.

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

person Kyle Maxwell    schedule 08.04.2013

Это возможно, но...

1) Сначала проверьте http://wiki.apache.org/solr/SurroundQueryParser (http://searchhub.org/2009/02/22/exploring-query-parsers/) для парсера объемных запросов. Это почти то, что вы хотите. Однако люди утверждают (по крайней мере, в некоторых местах), что он поддерживает фразовые запросы, но это неправда (пока).

2) Таким образом, вы должны реализовать фразу близости. (Неприятный) хак заключается в обновлении DistanceQuery::getSpanNearQuery (строка 78 в solr 4.2.1 в lucene/queryparser/.../DistanceQuery.java)

while (sqi.hasNext()) {
  SpanNearClauseFactory sncf = new SpanNearClauseFactory(reader, fieldName, qf);

  // HACK starts here 
  DistanceSubQuery dsq = ((DistanceSubQuery)sqi.next());
  try {
    if ( ((SrndTermQuery)dsq).getTermText().contains( " " ) ) {
      String term_text = ((SrndTermQuery)dsq).getTermText();
      String[] tokens = term_text.split("\\s+");
      SpanQuery[] span_queries = new SpanQuery[tokens.length];
      for ( int i = 0; i < tokens.length; ++i ) {
        span_queries[i] = new SpanTermQuery( new Term(fieldName, tokens[i]) );
      }
      spanClauses[qi] = new SpanNearQuery( span_queries, 0, true);
      qi++;
      continue;
    }
  }catch( Exception ex ){
  }
  // HACK ends here 

  dsq.addSpanQueries(sncf);

3) И будьте осторожны, чтобы не было предварительной обработки данных, поэтому, если вы используете поиск точных слов, например, select?q={!surround df=text}"мы определяем" 11w "спуск" будет соответствовать " "" определяем набор слов, отсортированных по убыванию """

person user2336968    schedule 30.04.2013