Я столкнулся с очень странным поведением, которое я считаю ошибкой, но я могу ошибаться или неправильно понимать документацию, поэтому я спрашиваю.
У меня есть индекс SOLR и я работаю с новыми функциямиверсия 4.0.
Это код, который я использую (я использую расширение PECL SOLR):
<code><?
$options = array (
'hostname' => '192.168.200.31',
'path' => 'solr/slave',
);
$client = new SolrClient($options);
$query = new SolrQuery();
#$query->setQuery("{!join from=id to=med_id }type:medium");
$query->setQuery("*:*");
$query->addFilterQuery('type:product');
$query->addFilterQuery("product_type:tv_free");
$query_response = $client->query($query);
$response = $query_response->getResponse();
echo '<pre>'.print_r($response,true)."
";?>
Код выше возвращает 38296
документов. Однако, если я раскомментирую строку #$query->setQuery("*:*");
, так что запрос теперь *:*
и эффективно соответствует каждому документу, я получу 21867
возвращенных документов - я думаю, что это правильное число.
Если вы хотите узнать немного больше о сценарии использования и о том, что стоит за этим, вы можете читать дальше, но это только справочная информация:
Я индексирую два типа документов, которые я различаю по значениюполя type
:
средний - в моем случае это фильм (например, аватар, касабланка и т. д.)
product -Это предложения для фильмов, как DVD наmazon
Причина такого разделения состоит в том, что я хочу фильтровать / фасетные запросы, которые позволяют пользователю, например, искать:
- фильм, который былвыпущено в период между 1990 и 1955 годами (эти метаданные хранятся в промежуточном документе)
- и доступно на amazon как DVD на 5% или менее (эта информация хранится в документе продукта)
- и это имеет слово «джунгли» в названии фильма (хранится в документе носителя)
Я делаю поиск (используя dismax) по всем документам типа «средний» с «джунглями» взаголовок:
$query->setQuery("{!type=dismax qf='$qf' mm='1' q.alt='*:*'}jungle");
Затем я добавляю фильтр запросов следующим образом:
$query->addFilterQuery("{!join from=med_id to=id}provider:amazon");
$query->addFilterQuery("{!join from=med_id to=id}price:[0 TO 500]"); // price is in cents
$query->addFilterQuery("release_year:[1990 TO 1995]");
Обратите внимание, что мне нужны первые два запроса в качестве соединения с документами типа prdouct, которые имеютполе с именем med_id, которое содержит идентификатор документа связанного с ними носителя типа.
Это все работает отлично!Тем не менее, я хочу, чтобы поиск по метаде проводился в документах типа product.Например, страна, где они доступны (где я могу заказать DVD)
Я получаю подсчет фасетов для всех полей, которые содержатся в средних документах из этой очереди, однако запросы на соединение не содержат никакой информации оисходные таблицы, используемые для фильтрации объединения с результатом.Поэтому мне нужен второй запрос:
Я делаю то же самое, что и выше, но на этот раз я использую запросы на своп-соединение, а не соединенные:
Так что мой запрос dismax теперь становится запросом на соединение:
$ query-> setQuery ("{! Join from = id to = med_id} {! Type = dismax qf = '$ qf' mm = '1' q.alt = ': '} jungle ");
Мои присоединенные запросы фильтра становятся обычными запросами фильтра:
$query->addFilterQuery("provider:amazon");
$query->addFilterQuery("price:[0 TO 500]");
А мой обычный запрос фильтра становится объединенным - на этот раз от идентификатора поля до med_id:
$ query-> addFilterQuery ("! Join from = id to = med_id} release_year: [1990 - 1995]");
Теперь возвращаются все продукты, соответствующие нашим фильтрам.Для одного носителя может быть более одного продукта - но я хочу, чтобы количество моих аспектов отражало количество фильмов, а не количество продуктов, поэтому я также группирую по med_id и устанавливаю усечение для группы в значение true так:
$query->addParam("group","true");
$query->addParam("group.field","med_id");
$query->addParam("group.truncate","true");
Единственная проблема с этим состоит в том, что запрос на соединение, выполняющий поиск в средних полях, заставляет мой запрос каким-то образом возвращать больше результатов, а не меньше, что я свел к минимальному коду в начале вопроса для воспроизведения.