Как фильтровать результаты поиска с использованием фасетов в Apache Lucene

#search #filter #lucene #full-text-search #facet

#Поиск #Фильтр #lucene #полнотекстовый поиск #фасет

Вопрос:

Я новичок в Apache Lucene и пытаюсь узнать, как фасеты Lucene можно использовать для моих нужд. Это мой сценарий.

1) Я выполнил текстовый поиск и получил документы D1, D2, D3, D4 и D5. 2) Созданные им фасеты F1, F2 и F3. 3) На основе результата поиска предположим, что фасеты указывают на соответствующие документы вместе с подсчетами. F1 (2 -> D1, D5), F2 (3-> D2, D4, D5) и F3 (2-> D2, D3)

4) Теперь давайте предположим, что существуют другие документы, такие как D6, D7, которые не являются частью результатов поиска, но существуют в индексе, и они также содержат фасет F1.

Теперь проблема, с которой я сталкиваюсь, заключается в следующем. 1) Когда я искал текст и получал документы от D1 до D5, я хочу дополнительно отфильтровать (сузить) результат поиска, используя фасет F1. Это означает, что в идеале из уже найденных результатов поиска, когда я использую фасет F1, я должен получить значения D1 и D5. Но на самом деле, когда я использовал фасет F1, я получаю документы D1, D5, D6 и D7 как часть фасета F1.

Итак, могу ли я не использовать фасет в качестве критерия фильтрации, чтобы еще больше сузить уже найденные результаты. Если да, пожалуйста, помогите мне с кодом. Если я тоже неправильно понимаю, пожалуйста, подскажите мне, как использовать фасеты для дальнейшего сужения уже найденных результатов, если это вообще возможно.Код, который я использую для выполнения, следующий. Я использую Apache Lucene 6.2.1.

         System.out.println("Enter query string:");
        String queryString = reader.readLine();
        QueryParser parser = new QueryParser("contents",
                new StandardAnalyzer());
        Query query = parser.parse(queryString);

        // TopDocs search = FacetsCollector.search(is, query, 10, srt, fc);
        TopDocs td1 = FacetsCollector.search(is, query, 10, fc);
        System.out.println("Total hits "   td1.totalHits);
        for (ScoreDoc scoreDoc : td1.scoreDocs) {
            Document doc = is.doc(scoreDoc.doc);
            System.out.println(
                    "Score-> "   scoreDoc.score   "::"   doc.get("price"));
        }
        Facets fcCount = new FastTaxonomyFacetCounts(tr, facetConfig_, fc);
        List<FacetResult> allDims = fcCount.getAllDims(100);
        for (int i = 0; i < allDims.size(); i  ) {
            FacetResult fr = allDims.get(i);
            System.out.println("Printing for dimension - "   fr.dim);
            LabelAndValue[] labelValues = fr.labelValues;
            for (int j = 0; j < labelValues.length; j  ) {
                System.out.println(labelValues[j].label   "::count->"
                          labelValues[j].value);
                System.out.println("Docs matching for dimension "   fr.dim
                          " with value "   labelValues[j].label);

                 /*Here I am trying to search using Facet-DIM, but have no way to connect it to already found search result.*/
                DrillDownQuery dq = new DrillDownQuery(facetConfig_);
                dq.add(fr.dim, labelValues[j].label);

                FacetsCollector fc1 = new FacetsCollector();
                TopDocs td2 = FacetsCollector.search(is, dq, 10, fc1);
                System.out.println("Total hits - "   td2.totalHits);
                for (ScoreDoc scoreDoc : td2.scoreDocs) {
                    Document doc = is.doc(scoreDoc.doc);
                    System.out.println("Score-> "   scoreDoc.score   "::"
                              doc.get("price"));
                }
                System.out.println("===DRILL DOWN END===");
            }
        } 
  

Ответ №1:

Вам нужно добавить свой поисковый запрос в качестве baseQuery DrillDownQuery конструктора:

 DrillDownQuery dq = new DrillDownQuery(facetConfig_, query);
  

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

Комментарии:

1. Спасибо, knutwalker, что помог мне здесь, и да, я заметил, что Facets понятия не имеет о результатах поиска как таковых.

Ответ №2:

Однако я нашел способ добиться этого, используя логический запрос, который объединяет поисковый запрос и запрос детализации с помощью Occurred .Фильтруйте следующим образом.

             BooleanQuery.Builder finalQueryBuilder = new BooleanQuery.Builder();
            finalQueryBuilder.add(searchQuery, Occur.MUST);
            FacetsConfig facetConfig = new FacetsConfig();
            DrillDownQuery dq = new DrillDownQuery(facetConfig);
            dq.add(qpKey, qpValue);
            finalQueryBuilder.add(dq, Occur.FILTER);
            TopDocs resultDocs = FacetsCollector.search(indexSearcher,
                    finalQueryBuilder.build(), Integer.MAX_VALUE, facetCollector);