2012-03-02 4 views
4

MongoDBでは、行セットのカーソルを返すfind()演算子が与えられています。「コンテキスト」行、つまり各行の前後の行を順番に返す慣用で時間効率の良い方法は何ですか?セット?MongoDB:指定された行の前後に順番に行を戻していますか?

この概念を説明する最も簡単な方法は、コンテキスト検索をサポートするackを使用することです。ファイルを考える:

line 1 
line 2 
line 3 
line 4 
line 5 
line 6 
line 7 
line 8 

これは、ACKから出力されます:

C:\temp>ack.pl -C 2 "line 4" test.txt 
line 2 
line 3 
line 4 
line 5 
line 6 

私はMongoDBのコレクション内のログデータを、行ごとに一つの文書を格納しています。それぞれのログはそれぞれキーワードにトークン化され、これらのキーワードは索引付けされています。これにより安価なフルテキスト検索が可能になります。

私は沼地標準を実行します。

collection.find({keywords: {'$all': ['key1', 'key2']}}, {}).sort({datetime: -1}); 

とカーソルを取得します。この段階で、追加のフィールドを追加することなく、コンテキストを取得する方法は何ですか?カーソル内の行ごとに

  • :私は流れのようなものだと思います
    • は_idフィールドを取得し、Xに格納します。 (N)
      • これらの各カーソルから結果を取得します。
    • 実行:collection.findを({_ ID:{ '$のLT':X}})ソート({_ ID:1})。限界(N)
      • これらの各々から結果を得ますカーソル。 R行と結果セットについて

これは2R + 1つのクエリを必要とします。

しかし、私は時間のためにスペースをトレードすることができると思います。バックグラウンドでコンテキストID _idを使って各行を更新することは可能ですか?現在のフィールドを持っている与えられた行の場合:

_id, contents, keywords 

私は、追加のフィールド追加します。

_id, contents, keywords, context_ids 

をしてから、私は、何とか、これらcontext_idsを使用することができ、その後の検索では、私が思いますか?私はまだMongoDB MapReduceに精通していませんが、それも同様に画像に入りますか?

私は、最も直接的なアプローチは、各行に実際のコンテキスト行のフルテキストを格納することだと思いますが、これは私にはやや粗悪なようです。明確な利点は、単一のクエリが必要なコンテキストを返すことができることです。

私は質問の範囲を受け入れるすべての答えを感謝します。私はLuceneや実際の全文検索エンジンを帯域外で使うことができることを認識していますが、MongoDB特有の答えに感謝するために、MongoDBの機能とエッジを理解しようとしています。ありがとう!

答えて

3

私はcontext_idsのようなものを保存するというアプローチが最良の選択肢かもしれないと思います。文脈のすべての行のcontext_idsを格納することができれば(これは固定サイズの量の文脈 - 前と後の5行を仮定していると仮定します)、次に文脈のすべての行を問い合わせることができます$in

# pseudocode 
for each matching row: 
    context_rows = db.logs.find({_id: {$in: row['context_ids']}}).sort({_id: 1}) 
    row_with_context = [context_rows_before_row] + row + [context_rows_after_row] 

私は、コンテキスト行のセットを知っていることを想像して - 任意の行の後の行は必ずしもまだ存在していますので、特に行あなたが検討している後の行を、困難な場合があります。

この問題を回避する(ただし、固定された既知の事前コンテキスト量が必要です)というのは、問題の行の前にコンテキストの最初の行の_idを格納することです挿入するには、Nは、コンテキストの量で、前のNライン)をバッファリングすることができます - このfirst_context_idを呼んで - してからのようなクエリ:あなたが必要としないので、これはまた、あなたのアプリケーションロジックを簡素化することが

# pseudocode 
for each matching row: 
    rows_with_context = db.logs.find({_id: {$gte: row['first_context_id']}}).sort({_id: 1}).limit(N * 2 + 1) 

問題の行でコンテキストを再構成するには、このクエリは一致した行とコンテキストの行の両方を返します。

関連する問題