Как использовать несколько фильтров для расширения поиска в запросах Apachesolr - PullRequest
6 голосов
/ 24 августа 2010

Выполняя поиск с помощью Apachesolr, я хочу добавить пару фильтров в hook_apachesolr_prepare_query (& $ query). Это работает хорошо, за исключением того, что я хочу, чтобы фильтры расширяли поиск ('ИЛИ'), а не сужали его ('И').

Например, если у меня есть 4 узла типа: A и 3 типа: B, которые соответствуют запросу, для фильтрации по типу: A и типу: B должно возвращаться 7 узлов (типа: A И узлы типа: B), а не 0 типа: A, которые также относятся к типу: B.

Я видел предложение сделать это, используя модель nodeaccess

foreach ($filters as $filter) {
  $subquery = apachesolr_drupal_query();
  if (!empty($subquery)) {
    $subquery->add_filter('type', $filter);
    $query->add_subquery($subquery);
  }
}

но это не похоже на работу. (Не дает никаких результатов).

Затем я попытался (поскольку у меня ограниченное количество типов узлов), исключая типы, которые мне не нужны:

$excludes = array('A', 'B', 'C');
$excludes = array_diff($excludes, $filters);
$exclude = implode('&', $excludes);
$query->add_filter('type', $exclude, TRUE);

Этот метод склеивания их не работает (экранирование '&'), но не добавляет их в качестве подзапросов, аналогично описанному выше.

Есть предложения, как это сделать?

Ответы [ 2 ]

2 голосов
/ 01 ноября 2012

С Drupal7 и последним API-интерфейсом apacheSolr вы можете выполнить ИЛИ-фильтры, выполнив следующее:

function my_module_apachesolr_query_alter($query) {
  // first, create a subQuery filter to store others
  // and specify there is a "OR" condition
  $filter = new SolrFilterSubQuery('OR');

  // next, add all filters on bundle you want, each as
  // a new subQuery filter, always with "OR" condition
  // and add it to the primary filter
  $a = new SolrFilterSubQuery('OR');
  $a->addFilter('bundle', 'A');
  $filter->addFilterSubQuery( $a );

  $b = new SolrFilterSubQuery('OR');
  $b->addFilter('bundle', 'B');
  $filter->addFilterSubQuery( $b );

  $c = new SolrFilterSubQuery('OR');
  $c->addFilter('bundle', 'C');
  $filter->addFilterSubQuery( $c );

  // finally, add the primary subQuery filter as
  // subquery of the current query 
  $query->addFilterSubQuery( $filter );

}

И ваш запрос поиска о типе А ИЛИ тип B ИЛИ тип C (все результаты в каждом типе). Вы можете объединить OR / AND, изменив параметр экземпляра SolrFilterSubQuery.

Отдельное спасибо этой странице и ее автору: http://fr.ench.info/blog/2012/04/03/Add-Filters-ApacheSOLR.html

0 голосов
/ 18 июля 2011

Я не очень много играл с SOLR, но я достаточно хорошо знаком с Drupal и Zend Lucene (или Drupal Lucene API).

Я бы посоветовал вам попытаться отфильтровать результаты по типу контента (потому что каждый узелимеет тип содержимого, хранящийся в объекте).

Вторая идея - изменить базовый оператор.Я не уверен, как это делается в SOLR, но я Zend Lucene

Zend_Search_Lucene_Search_QueryParser :: setDefaultOperator ($ operator) и Zend_Search_Lucene_Search_QueryParser :: getDefaultOperator (соответственно).

Документы можно найти в Документы Zend Lucene .Или для SOLR Solr Docs .

Я надеюсь, что ваша проблема правильно решена.

Надеюсь, это поможет: -)

...