要するに、複数のフィールドと値のマッピングを 1 つのインデックスから結果のインデックスに交換する必要があります。
以下はシナリオです。
インデックス 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..
結果のインデックスでは、keys<->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 であることを考えると、わずかな改善でも私のシナリオでは大きな影響があります。
総数 固有のキーワード数: 1,800 万。総数 一意の ID の数: 90 万
興味深い更新
最適化 1
- 新しいドキュメントを追加する際、複数の重複する 'Field' オブジェクトを作成する代わりに、" " 区切り文字を使用して単一の StringBuffer を作成し、全体を単一の Field として追加すると、最大 25% 改善されるようです。
更新 2: コード
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;
}