0

複数のテキスト ドキュメントのインデックスを作成しようとしています。

それらの内容は、フィールド タブで区切られた文字列です。

WORD<\t>w1<\t>w2<\t>...<\t>wn

POS<\t>pos1<\t>pos2_a:pos2_b:pos2_c<\t>...<\t>posn_a:posn_b
...

POS フィールドの場合、' で:'-区切られたトークンは同じあいまいな単語に対応します。

合計サイズが 10 MB の 5 つのドキュメントがあります。インデックス作成中、Java は約 2 GB の RAM を使用し、最終的に OOM エラーをスローします。

String join_token = tok.nextToken();
// atomic tokens correspond to separate parses
String[] atomic_tokens = StringUtils.split(join_token, ':');
// marking each token with the parse number
for (int token_index = 0; token_index < atomic_tokens.length; ++token_index) {
  atomic_tokens[token_index] += String.format("|%d", token_index);
}
String join_token_with_payloads = StringUtils.join(atomic_tokens, " ");
TokenStream stream = new WhitespaceTokenizer(Version.LUCENE_41, // OOM exception appears here
                                             new StringReader(join_token_with_payloads));
// all these parses belong to the same position in the document
stream = new PositionFilter(stream, 0);
stream = new DelimitedPayloadTokenFilter(stream, '|', new IntegerEncoder());
stream.addAttribute(OffsetAttribute.class);
stream.addAttribute(CharTermAttribute.class);
feature = new Field(name,
                    join_token,
                    attributeFieldType);
feature.setTokenStream(stream);
inDocument.add(feature);

メモリの観点から見たこのコードの何が問題なのですか? また、RAM に保持されるデータをできるだけ少なくしてインデックスを作成するにはどうすればよいでしょうか?

4

1 に答える 1

1

私が問題を正しく理解した場合(私はそれを試していませんでした)これは私の提案です

  1. Javaの規則であるコードでキャメルケースを使用することをお勧めします
  2. Field.TermVector.WITH_POSITIONS_OFFSETSを使用してフィールドを作成するだけで、位置を手動で生成する必要はありません。メトリックはインデックスに格納されます。
  3. Stringのこのような巨大な配列を作成すると、非常に大きなメモリオーバーヘッドが発生します->StringBuilderを使用します。
  4. LetterTokenizerを使用してストリームをトークン化するか、CharTokenizerを拡張して独自のトークナイザーを作成します
  5. ところで、素晴らしい本Lucene in Action
于 2013-03-18T13:15:31.713 に答える