Можно ли настроить Solr так, чтобы мощности в queryResponse.getFacetFields() отражали запрос в конъюнктивной нормальной форме?

Apache Solr API для граненого поиска очень интуитивен. С классом SolrQuery легко создавать конкатенированные запросы AND, выполнять тему в отношении хранилища и обрабатывать результаты. В качестве очень приятной функции Solr отправляет обратно объект queryResponse со списком FacetField, предоставляя адаптированные количества элементов оставшихся фасетов.

for ( FacetField facetField : queryResponse.getFacetFields() )
{
    logger.debug( facetField.getName() );
    for ( Count count : facetField.getValues() )
    {
        logger.debug( " " + count.getName() + "(" + count.getCount() + ")" );
    }
}

Мой вопрос: возможно ли настроить Solr таким образом, чтобы эти возвращаемые мощности отражали запросы в конъюнктивном нормальном формальном (CNF), другими словами, запросы AND-конкатенаций различных полей фасетов и OR-конкатенаций тех же полей фасетов?

По крайней мере, в конфигурации по умолчанию кажется, что в queryResponse.getFacetFields() допускаются только AND-сцепленные запросы. Я хотел бы использовать queryResponse.getFacetFields() без обходного пути и есть надежда, что проблема является вопросом конфигурации.

Для лучшего понимания здесь приведен конкретный пример использования с реальными и ожидаемыми возвращаемыми значениями API Solr: предполагается набор из 1000 элементов. Каждый элемент может иметь несколько назначений концепций и режимов коллекций. Таким образом, схема solr для документа элемента имеет два поля c для концепции и moc для режима сбора. Фасетный поиск включен для этих полей.

Надеемся, что легко понять, здесь соответствующие запросы в псевдокоде и мощности результирующих наборов. F(c:position) означает набор предметов, которым назначена концептуальная позиция, F(moc:postal) означает набор предметов, которым назначен режим сбора почтовых отправлений. Qi показывает запрос и результирующий набор, |Qi| это его мощность.

Q1: F(c:position) 
    -> |Q1| = 252
Q2: F(moc:telefonic) 
    -> |Q2| = 393
Q3: F(moc:postal) 
    -> |Q3| = 464
Q4: F(c:position) AND F(moc:telefonic) 
    -> |Q4| = 14 + 10 = 24
Q5: F(c:position) AND F(moc:postal) 
    -> |Q5| = 33 + 10 = 43
Q6: F(c:position) AND F(moc:telefonic) AND F(moc:postal) 
    -> |Q6| = 10
Q7: F(c:position) AND F(moc:telefonic) AND NOT F(moc:postal) 
    -> |Q7| = 14
Q8: F(c:position) AND F(moc:postal) AND NOT F(moc:telefonic) 
    -> |Q8| = 33
Q9: F(c:position) AND (F(moc:telefonic) OR F(moc:postal)) 
    -> |Q9| = 14 + 10 + 33 = 57

На следующем рисунке показана мощность множества и подмножеств:

Диаграмма Венна для граненого поиска

Теперь мы начинаем конкретный поиск: Q9 - интересующий запрос. Любые аспекты выбраны. Фасеты показывают ожидаемые значения: 252 для Q1, 393 для Q2 и 464 для Q3. Пользователь выбирает фасет c:position и уменьшает количество элементов набора результатов с 1000 до 252. Основной запрос - Q1. Возвращенные фасеты показывают 24 элемента для moc:telefonic и 43 предметов для moc:postal, Эти значения указывают, что выбор одного из этих аспектов будет ограничивать результирующий набор до 24 (= 14 + 10) или до 43 (= 33 + 10) элементов. На втором этапе пользователь дополнительно выбирает грань moc:postal, Основной запрос - Q5. Реальная и ожидаемая мощность набора результатов соответствуют друг другу, это 43. Пока все хорошо!

Какая мощность множества moc:telefonic теперь вы ожидаете, что вы получите ответ с запросом CNF с предыдущим выбором? Я ожидаю 14 пунктов. Если я выберу аспект moc:telefonic мой набор результатов увеличился бы с этих дополнительных предметов с 43 до 57. К сожалению, Солр показывает 10 предметов. Это было бы правильно, если бы все фасеты были AND-сцеплены. Как пользователь я запутался, потому что в моем наборе результатов 57 вместо 53 элементов.

// Q5: F(c:position) AND F(moc:postal) 
solrDocumentList = queryResponse.getResults();
assertEquals( 43, solrDocumentList.getNumFound() );
facetField = queryResponse.getFacetField( "moc" );
assertEquals( "telefonic", facetField.getValues().get( 0 ).getName() );

// test fails: returned value is 10
assertEquals( 14, facetField.getValues().get( 0 ).getCount() );

0 ответов

Другие вопросы по тегам