_id フィールドが多かれ少なかれランダムな場合に、キャップされたコレクション内のアイテムの範囲を取得する方法はありますか?
次のような単純な上限付きコレクションを作成したとします。
> db.createCollection("capped_test", {capped: true, size: 1048576})
{ "ok" : 1 }
> db.capped_test.insert({_id: 512, v: "test"})
> db.capped_test.insert({_id: 111, v: "test"})
> db.capped_test.insert({_id: 316, v: "test"})
> db.capped_test.insert({_id: 983, v: "test"})
> db.capped_test.insert({_id: 326, v: "test"})
私が探しているのは、_id: 111 から _id: 983 までの自然な順序でドキュメントを取得することです。
> db.capped_test.find({_id: {$gte: 111, $lte: 983}}).sort({$natural: 1})
すべてのドキュメントを取得します (すべての ID がこの範囲内にあるため、これは理にかなっています)。
{ "_id" : 512, "v" : "test" }
{ "_id" : 111, "v" : "test" }
{ "_id" : 316, "v" : "test" }
{ "_id" : 983, "v" : "test" }
{ "_id" : 326, "v" : "test" }
私が探しているのは、次の結果が得られるクエリです。
{ "_id" : 111, "v" : "test" }
{ "_id" : 316, "v" : "test" }
{ "_id" : 983, "v" : "test" }
これは可能ですか?
私の実際のユースケースには、多くのクライアントが単一の上限付きコレクションに書き込むことが含まれます。周期性、前回のマップ削減ジョブが実行されてから追加されたデータの集計を計算するマップ削減ジョブを開始したいと思います。そのため、オプションとして db.collection.mapReduce() に渡すことができるクエリ オブジェクトが役立ちます。
編集:
明確にするために、ObjectID を使用していて、複数のクライアントが同じコレクションに書き込みを行っている場合、同じ問題が存在するように見えます。ObjectID がObjectId("ttttttttmmmmmmppppcccccc")
t がタイムスタンプ、m がマシン ID、p がプロセス ID、c がカウンターである場合、同じタイムスタンプ内にすべてドキュメントを挿入する複数のクライアントをシミュレートできます。
> db.createCollection("capped_test", {capped: true, size: 1048576})
{ "ok" : 1 }
>
> // Client with machine id 1 writes
> db.capped_test.insert({_id: ObjectId("000000010000010000000000"), v: "test"})
> db.capped_test.insert({_id: ObjectId("000000010000010000000001"), v: "test"})
> db.capped_test.insert({_id: ObjectId("000000010000010000000002"), v: "test"})
>
> // Client with machine id 2 writes
> db.capped_test.insert({_id: ObjectId("000000010000020000000000"), v: "test"})
> db.capped_test.insert({_id: ObjectId("000000010000020000000001"), v: "test"})
>
> // Client with mahcine id 1 writes again
> db.capped_test.insert({_id: ObjectId("000000010000010000000003"), v: "test"})
> db.capped_test.insert({_id: ObjectId("000000010000010000000004"), v: "test"})
2 番目と最後から 2 番目のドキュメントの間のすべてのドキュメントのクエリ:
> db.capped_test.find({_id: {$gte: ObjectId("000000010000010000000001"), $lte: ObjectId("000000010000010000000003")}}).sort({$natural: 1})
{ "_id" : ObjectId("000000010000010000000001"), "v" : "test" }
{ "_id" : ObjectId("000000010000010000000002"), "v" : "test" }
{ "_id" : ObjectId("000000010000010000000003"), "v" : "test" }
望ましい結果が次の場合:
{ "_id" : ObjectId("000000010000010000000001"), "v" : "test" }
{ "_id" : ObjectId("000000010000010000000002"), "v" : "test" }
{ "_id" : ObjectId("000000010000020000000000"), "v" : "test" }
{ "_id" : ObjectId("000000010000020000000001"), "v" : "test" }
{ "_id" : ObjectId("000000010000010000000003"), "v" : "test" }