【问题标题】:How to filter search results using facets in Apache Lucene如何使用 Apache Lucene 中的构面过滤搜索结果
【发布时间】:2016-10-13 06:48:49
【问题描述】:

我是 Apache Lucene 的新手,正在尝试了解如何使用 Lucene Facets 来满足我的需求。这是我的场景。

1) 我进行了文本搜索,得到了文档 D1、D2、D3、D4 和 D5。 2) 它创建了 F1、F2 和 F3 的方面。 3)根据搜索结果,我们假设 facets 与计数一起指向相应的文档。 F1 (2 ->D1, D5) , F2 (3->D2,D4,D5) 和 F3 (2->D2,D3)

4) 现在假设存在其他文档,例如 D6、D7,它们不是搜索结果的一部分,但存在于索引中,并且它们还包含 facet F1。

现在我面临的问题如下。 1)当我用文本搜索并获得从 D1 到 D5 的文档时,我想使用 F1 facet 进一步过滤(缩小)搜索结果。这意味着,理想情况下,当我使用 facet F1 时,从已经找到的搜索结果中,我应该得到 Dcoument D1 和 D5。但实际上,当我使用 Facet F1 时,我将 D1、D5、D6 和 D7 文档作为 facet 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===");
            }
        } 

【问题讨论】:

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


    【解决方案1】:

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

    DrillDownQuery dq = new DrillDownQuery(facetConfig_, query);
    

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

    【讨论】:

    • 感谢 knutwalker 在这里帮助我,是的,我观察到 Facets 不知道这样的搜索结果。
    【解决方案2】:

    但是,我找到了一种方法来实现它,通过使用以下方式将搜索查询和 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-07
      • 1970-01-01
      • 1970-01-01
      • 2012-05-18
      • 2012-08-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多