2012-07-31 5 views
0

즉, 하나의 인덱스에서 결과 인덱스로 여러 필드와 값의 매핑을 교환해야합니다.Lucene 성능 : 하나의 인덱스에서 다른 인덱스로 필드 데이터를 전송

다음은 시나리오입니다.

인덱스 1 구조 [필드 => 값 [저장]

Doc 1  
keys => keyword1;  
Ids => id1, id1, id2, id3, id7, id11, etc.. 

Doc 2  
keys => keyword2;  
Ids => id3, id11, etc.. 

인덱스 2 구조 [필드 => 값 [저장]

Doc 1  
ids => id1  
keys => keyword1, keyword1 

Doc 3  
ids => id3  
keys => keyword1, keyword2, etc.. 

도와주세요 키 < -> ids 매핑이 결과 색인에서과 반대로 실행됨을 나타냅니다.

시간 복잡성 측면에서 이것을 달성하는 가장 효과적인 방법은 무엇이라고 생각하십니까? .. 내가 생각할 수

유일한 방법은 즉 ..

1) index1Reader.terms();  
2) Process only terms belonging to "Ids" field  
3) For each term, get TermDocs  
4) For each doc, load it, get "keys" field info  
5) Create a new Lucene Doc, add 'Id', multi Keys, write it to index2.  
6) Go to step 2. 

필드가 저장되어 있기 때문에, 내가 그 일을 여러 가지 방법이 있다는 것을 확신합니다.

성능 기술로 안내해주십시오. 심지어 약간의 개선은 Index1 크기가 ~ 6GB라고 생각할 때 내 시나리오에 큰 영향을 미칩니다.

총계. 고유 키워드 : 1800 만; 총계. 의 고유 ID : 0900000

재미있는 UPDATE

최적화 1

  • 있는 단일의 StringBuffer를 만드는 대신 여러 중복 '필드'객체를 생성하는 새로운 문서를 추가하는 동안 " "구분 기호를 사용하고 전체 필드를 하나의 필드로 추가하면 최대 25 %의 향상이있는 것으로 보입니다.

업데이트 2 : 코드 FieldCache의

public void go() throws IOException, ParseException { 
    String id = null; 
    int counter = 0; 
    while ((id = getNextId()) != null) { // this method is not taking time.. 
     System.out.println("Node id: " + id); 
     updateIndex2DataForId(id); 
     if(++counter > 10){ 
      break; 
     } 
    } 
    index2Writer.close(); 
} 

private void updateIndex2DataForId(String id) throws ParseException, IOException { 
    // Get all terms containing the node id 
    TermDocs termDocs = index1Reader.termDocs(new Term("id", id)); 
    // Iterate 
    Document doc = new Document(); 
    doc.add(new Field("id", id, Store.YES, Index.NOT_ANALYZED)); 
    int docId = -1;   
    while (termDocs.next()) { 
     docId = termDocs.doc(); 
     doc.add(getKeyDataAsField(docId, Store.YES, Index.NOT_ANALYZED));    
    } 
    index2Writer.addDocument(doc); 
} 

private Field getKeyDataAsField(int docId, Store storeOption, Index indexOption) throws CorruptIndexException, 
     IOException { 
    Document doc = index1Reader.document(docId, fieldSelector); // fieldSel has "key" 
    Field f = new Field("key", doc.get("key"), storeOption, indexOption); 
    return f; 
} 
+0

은 단 한 번의 일입니까?내 추측으로 생각하면 시간은 최적화에서 절약 한 시간보다 더 컸을 것입니다 ... 6GB는 큰 지수이지만 lucene은이 물건들을 아주 빨리 처리 할 수 ​​있습니다 ... 당신이 볼 수있는 짐승 테스트를 해 봤나? 얼마나 걸릴까요? –

+0

답장을 보내 주셔서 감사합니다. 비록 그것이 일회성 일이긴하지만, 나는 그것의 마감 시간 전에 두 번해야 할 수도 있습니다. 따라서 perf impr을 생각해보십시오. 그래, 위의 방법을 시도했지만, 시간 소비 조금 실망입니다. 각 문서에 대해 여러 초 (2-5 +) 걸립니다. 총계. 예상 문서의 최대 크기는 백만 분의 1입니다. – phani

+0

프로필 작성에 오래 걸리는 부분은 무엇입니까? –

답변

0

사용은 우리가 힙에 모든 필드를 수용하기 위해 점점 더 많은 RAM을 충당 할 필요가 마법처럼 일했다 ...하지만. 그것은 빨리 모든 것을 만들어

private void updateIndex2DataForId(String id) throws ParseException, IOException { 
    // Get all terms containing the node id 
    TermDocs termDocs = index1Reader.termDocs(new Term("id", id)); 
    // Iterate 
    Document doc = new Document(); 
    doc.add(new Field("id", id, Store.YES, Index.NOT_ANALYZED)); 
    int docId = -1; 
    StringBuffer buffer = new StringBuffer(); 
    while (termDocs.next()) { 
     docId = termDocs.doc(); 
     buffer .append(keys[docId] + " "); // keys[] is pre-populated using FieldCache     
    } 
    doc.add(new Field("id", buffer.trim().toString(), Store.YES, Index.ANALYZED)); 
    index2Writer.addDocument(doc); 
} 

String[] keys = FieldCache.DEFAULT.getStrings(index1Reader, "keywords"); 

내가 다음 코드와 위의 updateIndex2DataForId()를 업데이트했습니다

은 .. 나는 당신에게 정확한 측정을 말할 수 없다하지만 난 아주 중요한 말을해야합니다.

이제 프로그램이 적당한 시간 내에 완료됩니다. 어쨌든, 추가 지침은 높게 평가됩니다.

+0

Doh. fieldcache를 사용하는 것에 대해 생각조차하지 않았다. 그리고 나는 단지 3GB로 상상할 것이다. 당신이 이것을 비명을 지르기 위해 조금 더 필요할 것이다. –

관련 문제