将lucene指数分成两半

将lucene指数分成两半,lucene,Lucene,将现有Lucene索引拆分为两半的最佳方法是什么?即,每个拆分应包含原始索引中文档总数的一半。一个相当强大的机制是使用文档校验和,对索引数进行模化,要决定它将进入哪个索引。拆分现有索引(无需重新编制所有文档的索引)的最简单方法是: 制作现有索引的另一个副本(即cp-r myindex mycopy) 打开第一个索引,删除一半文档(范围0到maxDoc/2) 打开第二个索引,并删除另一半(范围为maxDoc/2到maxDoc) 优化这两个指标 这可能不是最有效的方法,但它只需要很少的编码。Luce

将现有Lucene索引拆分为两半的最佳方法是什么?即,每个拆分应包含原始索引中文档总数的一半。一个相当强大的机制是使用文档校验和,对索引数进行模化,要决定它将进入哪个索引。

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

  • 制作现有索引的另一个副本(即cp-r myindex mycopy)
  • 打开第一个索引,删除一半文档(范围0到maxDoc/2)
  • 打开第二个索引,并删除另一半(范围为maxDoc/2到maxDoc)
  • 优化这两个指标

  • 这可能不是最有效的方法,但它只需要很少的编码。

    Lucene的最新版本有一个专门的工具来实现这一点(
    indexplitter
    contrib/misc下的multipassindexplitter

    这个问题是我在研究这个问题的答案时发现的第一个问题,所以我将我的解决方案留给后代。在我的例子中,我需要沿着特定的线分割索引,而不是随意地从中间向下或分成三分之一,或者诸如此类。这是一个使用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();
        }
    }
    
    var distinctPlantIDs=databaseRepo.GetDistinctPlantIDs();
    var sourceDir=GetOldIndexDir();
    foreach(distinctPlantIDs中的var plantID)
    {
    var query=newtermquery(新术语(“PlantID”,PlantID.ToString());
    var targetDir=GetNewIndexDirForPlant(plantID);//返回此工厂索引所在的唯一目录
    //阅读每个工厂的文档并将其写入新索引
    使用(var analyzer=新的StandardAnalyzer(Version.LUCENE_30,CharArraySet.EMPTY_SET))
    使用(var sourceSearcher=newindexsearcher(sourceDir,true))
    使用(var destWriter=new IndexWriter(targetDir,analyzer,true,IndexWriter.MaxFieldLength.UNLIMITED))
    {
    var numHits=sourceSearcher.DocFreq(query.Term);
    
    如果(numHits只是为了清楚:您希望在不重新编制文档索引的情况下拆分索引,对吗?是的,您是对的!我不想重新读取索引,然后再次使用IndexWriter构建两个索引。相反,一些自动的方法似乎可以提供一些商业理由吗?最简单的方法是读取并循环索引xReader类。