如何使用Apache Lucene中的facet过滤搜索结果

时间:2016-10-13 06:48:49

标签: search filter lucene full-text-search facet

我是Apache Lucene的新手,并试图了解Lucene Facets如何用于我的需要。这是我的情景。

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 facet进一步过滤(缩小)搜索结果。这意味着,理想情况下,当我使用方面F1时,已经找到的搜索结果,我应该得到Dcoument D1和D5。但实际上,当我使用Facet F1时,我将D1,D5,D6和D7文档作为方面F1的一部分。

因此,我是否可以不使用facet作为过滤条件来进一步缩小已搜索结果的范围。如果是这样,请帮我解释一下代码。如果我的理解也错了,请指导我如何使用facet进一步缩小已经搜索过的结果,如果可能的话。我正在使用的代码如下。我正在使用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===");
            }
        } 

2 个答案:

答案 0 :(得分:1)

您需要将搜索查询baseQuery添加到DrillDownQuery构造函数中:

DrillDownQuery dq = new DrillDownQuery(facetConfig_, query);

facet结果不知道原始查询是什么,它只是一堆标签和值,因此您使用的构造函数将始终在所有文档上运行构面值。

答案 1 :(得分:0)

然而,我找到了一种方法来实现它,通过一个布尔查询,将搜索查询和DrillDownQuery与Occur.Filter结合使用,具有以下方式。

            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);