2010-07-21 7 views
7

10,000 개의 문서를 IndexWriter에 추가 한 작은 루프를 작성하여이를 수행하는 데 오래 걸렸습니다.Lucene IndexWriter 문서를 추가하는 속도가 느림

많은 양의 문서를 색인하는 또 다른 방법이 있습니까?

라이브가되면 15,000 개의 레코드를로드해야하기 때문에 질문합니다.

또 다른 질문은 웹 응용 프로그램을 다시 시작할 때 모든 레코드를 다시로드하지 않아도되는 방법입니다. 편집

제가 사용되는 코드이며;

for (int t = 0; t < 10000; t++){ 
    doc = new Document(); 
    text = "Value" + t.toString(); 
    doc.Add(new Field("Value", text, Field.Store.YES, Field.Index.TOKENIZED)); 
    iwriter.AddDocument(doc); 
}; 

편집

 Analyzer analyzer = new StandardAnalyzer(); 
     Directory directory = new RAMDirectory(); 

     IndexWriter iwriter = new IndexWriter(directory, analyzer, true); 

     iwriter.SetMaxFieldLength(25000); 

(2) 다음의 코드는 다음, 문서를 추가 할;

 iwriter.Close(); 
+1

얼마나 오래 되었습니까? –

+0

약 2.5 ~ 3 분이 소요되었습니다. 예상 되나요? – griegs

+0

문서에 단일 필드가 있고 필드의 값이 "value"+ t.toString() 인 것으로 추가해야합니다. 매우 작음 – griegs

답변

5

확인 만하고 실행하면 디버거가 연결되지 않았습니까?

이렇게하면 문서를 추가 할 때 성능에 심각한 영향을줍니다. 내 컴퓨터에

(루씬 2.0.0.4) :

플랫폼 대상 86와 내장

:

  • 디버거 -

  • 디버거가 부착 된 5.2 초 - 113.8 초

플랫폼 타겟으로 구축 x64 :

  • 디버거 -

  • 디버거가 부착 된 6.0 초 - 171.4 초

    절약에와 RAMDirectory에서 인덱스를로드하는

거친 예 :

const int DocumentCount = 10 * 1000; 
const string IndexFilePath = @"X:\Temp\tmp.idx"; 

Analyzer analyzer = new StandardAnalyzer(); 
Directory ramDirectory = new RAMDirectory(); 

IndexWriter indexWriter = new IndexWriter(ramDirectory, analyzer, true); 

for (int i = 0; i < DocumentCount; i++) 
{ 
    Document doc = new Document(); 
    string text = "Value" + i; 
    doc.Add(new Field("Value", text, Field.Store.YES, Field.Index.TOKENIZED)); 
    indexWriter.AddDocument(doc); 
} 

indexWriter.Close(); 

//Save index 
FSDirectory fileDirectory = FSDirectory.GetDirectory(IndexFilePath, true); 
IndexWriter fileIndexWriter = new IndexWriter(fileDirectory, analyzer, true); 
fileIndexWriter.AddIndexes(new[] { ramDirectory }); 
fileIndexWriter.Close(); 

//Load index 
FSDirectory newFileDirectory = FSDirectory.GetDirectory(IndexFilePath, false); 
Directory newRamDirectory = new RAMDirectory(); 
IndexWriter newIndexWriter = new IndexWriter(newRamDirectory, analyzer, true); 
newIndexWriter.AddIndexes(new[] { newFileDirectory }); 

Console.WriteLine("New index writer document count:{0}.", newIndexWriter.DocCount()); 
+0

+1, 감사합니다. 오늘 밤 이걸 살펴볼 것입니다. 나는 그것이 디버거일지도 모른다고 생각한다. 도와 주셔서 감사합니다 – griegs

+0

도와 주셔서 감사합니다. 나는 네가 훌륭한 시간을 얻지 못하고있다. 제 생각에 받아 들일 수있는 16 초입니다. 내 하드웨어가 된 것 같아. – griegs

10

당신에게 최상의 성능을 얻으려면이 방법을 사용해야합니다.내 컴퓨터에서 나는 당신이 스레딩을 사용할 수있는 및 후이

private static void IndexingThread(object contextObj) 
{ 
    Range<int> range = (Range<int>)contextObj; 
    Document newDoc = new Document(); 
    newDoc.Add(new Field("title", "", Field.Store.NO, Field.Index.ANALYZED)); 
    newDoc.Add(new Field("body", "", Field.Store.NO, Field.Index.ANALYZED)); 
    newDoc.Add(new Field("newsdate", "", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); 
    newDoc.Add(new Field("id", "", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); 

    for (int counter = range.Start; counter <= range.End; counter++) 
    { 
     newDoc.GetField("title").SetValue(Entities[counter].Title); 
     newDoc.GetField("body").SetValue(Entities[counter].Body); 
     newDoc.GetField("newsdate").SetValue(Entities[counter].NewsDate); 
     newDoc.GetField("id").SetValue(Entities[counter].ID.ToString()); 

     writer.AddDocument(newDoc); 
    } 
} 

같은 문서를 추가 일초 재사용해야

1) (문서, 필드)마다 생성하지에 색인 1000 문서 해요 작은 것들로 큰 컬렉션을 중단하고 10,000 문서가있을 경우 10 스레드 ThreadPool이를 사용하여 만들 수 있습니다 예를 들어 각 섹션 에 대해 위의 코드를 사용하고 그럼 당신은 얻을 것

색인

에 대한 하나의 스레드에 각 섹션을 피드 최고의 성능.

+0

+1 @Ehsan, 고맙습니다. 나는 오늘 그것을 시험해 볼 것이다. – griegs

관련 문제