代码之家  ›  专栏  ›  技术社区  ›  Kris

Lucene 3迭代所有点击

  •  2
  • Kris  · 技术社区  · 14 年前

    我正在更新一个使用Lucene索引的工具。作为这次更新的一部分,我们将从lucene2.0.0升级到3.0.2。在很大程度上,这是完全直截了当的。然而,在一个例子中,我似乎找不到一个直接的转换。

    击打。在Lucene 2中,这很简单,例如:

    Hits hits = indexSearcher.search(query);
    for(int i=0 ; i<hits.length() ; i++){
      // Process hit
    }
    

    IndexSearcher 已经发生了很大的变化,尽管我可以把一些有用的东西拼凑起来,但这只能通过得到顶端 X 并确保

    虽然点击的数量(在我的例子中)通常在0到10之间,但也有一些异常情况,它们的数量可能会高得多。有一个固定的限制是不对的。此外,将限制设置得很高会导致OOME,这意味着所有人都有空间 立即分配可能的命中。执行此操作时 很多 ,需要一些合理有效的东西。

    目前我有以下工作要做:

    TopDocs hits = indexSearcher.search(query, MAX_HITS);
    for (int i=0 ; i<hits.totalHits ; i++) {
       // Process hit
    }
    

    这个很好,除了那个

    (一) 如果有更多的点击呢 MAX_HITS

    (二) 如果MAX\u HITS很大,那么我是在浪费内存,因为在执行搜索之前已经为每个命中分配了空间。

    由于大多数时候只有几次点击,我不介意做后续搜索,以获得后续的点击,但我似乎找不到一个方法来做到这一点。

    4 回复  |  直到 14 年前
        1
  •  2
  •   Kris    14 年前

    IndexSearcher有一个方法 docFreq(Term) . 调用它似乎没有性能损失,它的输出是一个合适的输入参数,用于获取文档的数量。

    int freq = searcher.docFreq(new Term(FIELD, value));
    TopDocs hits = indexSearcher.search(query, freq);
    for (int i=0 ; i<hits.totalHits ; i++) {
       // Process hit
    }
    

    这是因为我的查询本质上是一个 TermQuery

        2
  •  2
  •   user332699    13 年前

    @克里斯-我也遇到了这个问题,这对我很有效。试试这个:

    TopDocs tp = ms.search(query, 1); 
    
    TopDocs hits = indexSearcher.search(query, tp.totalHits);
    for (int i=0 ; i<hits.totalHits ; i++) {
       // Process hit
    }
    

    根据Uwe在下面的链接tp.totalHits“。。仍将计算所有命中数,但只返回1。“

    请参阅java用户lucene apache邮件存档链接中的完整详细信息- http://www.gossamer-threads.com/lists/lucene/java-user/95032

        3
  •  0
  •   bajafresh4life    14 年前

    为什么不使用Searcher.search(Query Query,int n)?您可以指定要返回的结果数,并且可以使用返回的TopDocs对象来迭代结果。

    使用Hits来处理长的结果集是个坏主意,因为在后台Hits对象会运行更多的搜索来填充它还没有的结果。

    TopDocs只包含id和scores,所以即使对于大的n,也不应该有内存问题。

        4
  •  0
  •   Adrian Conlon    14 年前

    使用索引读取器中的NumDocs作为最大结果数怎么样。

    注意索引中零文档的边缘情况。。。