将lucene指数分成两半

时间:2010-05-19 13:37:09

标签: lucene

将现有Lucene索引拆分为两半的最佳方法是什么,即每个拆分应包含原始索引中文档总数的一半

4 个答案:

答案 0 :(得分:3)

拆分现有索引(不重新索引所有文档)的最简单方法是:

  1. 制作现有索引的另一个副本(即cp -r myindex mycopy)
  2. 打开第一个索引,删除一半文档(范围0到maxDoc / 2)
  3. 打开第二个索引,删除另一半(范围maxDoc / 2到maxDoc)
  4. 优化两个指数
  5. 这可能不是最有效的方法,但它只需要很少的编码。

答案 1 :(得分:1)

一个相当强大的机制是使用文档的校验和,以索引的数量为模,来决定它将进入哪个索引。

答案 2 :(得分:1)

Lucene的最新版本有一个专门的工具来执行此操作(在contrib / misc下的IndexSplitterMultiPassIndexSplitter

答案 3 :(得分:0)

这个问题是我在研究这个问题的答案时发现的第一个问题,因此我将这个解决方案留给了后代。在我的情况下,我需要沿着特定的行分割我的索引,而不是任意地在中间或三分之一或你有什么。这是使用Lucene 3.0.3的C#解决方案。

我的应用程序的索引大小超过300GB,这有点难以管理。索引中的每个文档都与使用该应用程序的制造工厂之一相关联。没有商业原因,一家工厂会搜索另一家工厂的数据,所以我需要沿着这些线干净地划分指数。这是我写的代码:

var distinctPlantIDs = databaseRepo.GetDistinctPlantIDs();
var sourceDir = GetOldIndexDir();
foreach (var plantID in distinctPlantIDs)
{
    var query = new TermQuery(new Term("PlantID", plantID.ToString()));
    var targetDir = GetNewIndexDirForPlant(plantID); //returns a unique directory where this plant's index will go

    //read each plant's documents and write them to the new index
    using (var analyzer = new StandardAnalyzer(Version.LUCENE_30, CharArraySet.EMPTY_SET))
    using (var sourceSearcher = new IndexSearcher(sourceDir, true))
    using (var destWriter = new IndexWriter(targetDir, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED))
    {
        var numHits = sourceSearcher.DocFreq(query.Term);
        if (numHits <= 0) continue;
        var hits = sourceSearcher.Search(query, numHits).ScoreDocs;
        foreach (var hit in hits)
        {
            var doc = sourceSearcher.Doc(hit.Doc);
            destWriter.AddDocument(doc);
        }
        destWriter.Optimize();
        destWriter.Commit();
    }

    //delete the documents out of the old index
    using (var analyzer = new StandardAnalyzer(Version.LUCENE_30, CharArraySet.EMPTY_SET))
    using (var sourceWriter = new IndexWriter(sourceIndexDir, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED))
    {
        sourceWriter.DeleteDocuments(query);
        sourceWriter.Commit();
    }
}

那个从旧索引中删除记录的部分就在那里,因为在我的情况下,一个工厂的记录占据了索引的大部分(超过2 / 3rds)。因此,在我的真实版本中,有一些额外的代码可以最后完成该工厂,而不是像其他工具那样将其拆分,它将优化剩余的索引(这只是工厂),然后将其移动到新目录。

无论如何,希望这可以帮助那些人。