【问题标题】:Finding total number of matches to a query with lucene使用 lucene 查找查询的匹配总数
【发布时间】:2012-09-25 15:49:34
【问题描述】:

我是 lucene 新手,所以我不知道这是否可能,但我有一个索引,我想获取索引子集中的短语总数(子集由过滤器定义)。 我可以将 FilteredQuery 与我的过滤器和 PhraseQuery 一起使用来搜索短语,因此我可以计算出现此短语的文档,但我似乎也无法找到一种方法来计算每个文档的匹配数。

【问题讨论】:

    标签: lucene


    【解决方案1】:

    您可以这样做,有关详细信息,请参阅LUCENE-2590

    您可以查看unit tests 的示例代码以了解此功能。

    我在下面复制了短语搜索器的相关代码,

    这是收集器,

    private static class CountingCollector extends Collector {
      private final Collector other;
      private int docBase;
    
      public final Map<Integer, Map<Query, Float>> docCounts = new HashMap<Integer, Map<Query, Float>>();
    
      private final Map<Query, Scorer> subScorers = new HashMap<Query, Scorer>();
      private final ScorerVisitor<Query, Query, Scorer> visitor = new MockScorerVisitor();
      private final EnumSet<Occur> collect;
    
      private class MockScorerVisitor extends ScorerVisitor<Query, Query, Scorer> {
    
        @Override
        public void visitOptional(Query parent, Query child, Scorer scorer) {
          if (collect.contains(Occur.SHOULD))
            subScorers.put(child, scorer);
        }
    
        @Override
        public void visitProhibited(Query parent, Query child, Scorer scorer) {
          if (collect.contains(Occur.MUST_NOT))
            subScorers.put(child, scorer);
        }
    
        @Override
        public void visitRequired(Query parent, Query child, Scorer scorer) {
          if (collect.contains(Occur.MUST))
            subScorers.put(child, scorer);
        }
    
      }
    
      public CountingCollector(Collector other) {
        this(other, EnumSet.allOf(Occur.class));
      }
    
      public CountingCollector(Collector other, EnumSet<Occur> collect) {
        this.other = other;
        this.collect = collect;
      }
    
      @Override
      public void setScorer(Scorer scorer) throws IOException {
        other.setScorer(scorer);
        scorer.visitScorers(visitor);
      }
    
      @Override
      public void collect(int doc) throws IOException {
        final Map<Query, Float> freqs = new HashMap<Query, Float>();
        for (Map.Entry<Query, Scorer> ent : subScorers.entrySet()) {
          Scorer value = ent.getValue();
          int matchId = value.docID();
          freqs.put(ent.getKey(), matchId == doc ? value.freq() : 0.0f);
        }
        docCounts.put(doc + docBase, freqs);
        other.collect(doc);
      }
    
      @Override
      public void setNextReader(IndexReader reader, int docBase)
          throws IOException {
        this.docBase = docBase;
        other.setNextReader(reader, docBase);
      }
    
      @Override
      public boolean acceptsDocsOutOfOrder() {
        return other.acceptsDocsOutOfOrder();
      }
    }
    

    单元测试是,

    @Test
    public void testPhraseQuery() throws Exception {
      PhraseQuery q = new PhraseQuery();
      q.add(new Term("f", "b"));
      q.add(new Term("f", "c"));
      CountingCollector c = new CountingCollector(TopScoreDocCollector.create(10,
          true));
      s.search(q, null, c);
      final int maxDocs = s.maxDoc();
      assertEquals(maxDocs, c.docCounts.size());
      for (int i = 0; i < maxDocs; i++) {
        Map<Query, Float> doc0 = c.docCounts.get(i);
        assertEquals(1, doc0.size());
        assertEquals(2.0F, doc0.get(q), FLOAT_TOLERANCE);
    
        Map<Query, Float> doc1 = c.docCounts.get(++i);
        assertEquals(1, doc1.size());
        assertEquals(1.0F, doc1.get(q), FLOAT_TOLERANCE);
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-01
      • 2011-02-20
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 2017-08-12
      相关资源
      最近更新 更多