расщепление люценового индекса на две половины - PullRequest
2 голосов
/ 19 мая 2010

каков наилучший способ разбить существующий индекс Lucene на две половины, т. Е. Каждое разбиение должно содержать половину от общего количества документов в исходном индексе

Ответы [ 4 ]

3 голосов
/ 20 мая 2010

Самый простой способ разделить существующий индекс (без переиндексации всех документов) - это:

  1. Сделайте еще одну копию существующего индекса (то есть cp -r myindex mycopy)
  2. Открыть первый индекс и удалить половину документов (от 0 до maxDoc / 2)
  3. Открыть второй индекс и удалить другую половину (диапазон от maxDoc / 2 до maxDoc)
  4. Оптимизировать оба индекса

Вероятно, это не самый эффективный способ, но для этого требуется очень мало кодирования.

1 голос
/ 13 мая 2011

В последних версиях Lucene есть специальный инструмент для этого (IndexSplitter и MultiPassIndexSplitter в contrib / misc).

1 голос
/ 19 мая 2010

Достаточно надежный механизм - использовать контрольную сумму документа по модулю количества индексов, чтобы решить, в какой индекс он войдет.

0 голосов
/ 05 мая 2018

Этот вопрос был одним из первых, которые я нашел, когда искал ответы на эту проблему, поэтому я оставляю свое решение здесь для будущих поколений. В моем случае мне нужно было разделить мой индекс по определенным линиям, а не произвольно вниз по середине или на трети или что там у вас. Это решение C # с использованием Lucene 3.0.3.

Индекс моего приложения превышает 300 ГБ, что становится немного неуправляемым. Каждый документ в индексе связан с одним из заводов-изготовителей, который использует приложение. Нет никаких бизнес-причин, по которым одно предприятие будет когда-либо искать данные другого, поэтому мне нужно было аккуратно разделить индекс по этим линиям. Вот код, который я написал для этого:

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/3). Так что в моей реальной версии есть некоторый дополнительный код для того, чтобы сделать это растение последним, и вместо того, чтобы разделять его, как другие, он оптимизирует оставшийся индекс (который является просто этим растением), а затем переместит его в новый каталог.

В любом случае, надеюсь, это поможет кому-то там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...