0

mongo db に「votes」フィールドを含むブログ投稿のコレクションがあります。

> db.posts.find({}, {_id:0, votes: 1})
{ "votes" : 1 }
{ "votes" : 2 }
{ "votes" : 2 }
{ "votes" : 3 }
{ "votes" : 3 }

ページごとに 1 つの投稿を表示する Web インターフェイスと、投票によって投稿を並べ替えるためのコントロール (次、前) があります。次/前の投稿のリクエストを現在の投票数でサーバーに送信し、新しい投稿を選択します。だから私は次のクエリを取得します(httpリクエストごとに1つ)

> db.things.find({vote: {$gt: 0}}, {_id:0, votes:1}).limit(1) // current votes == 0
{ "votes" : 1 }
> db.things.find({vote: {$gt: 1}}, {_id:0, votes:1}).limit(1) // current votes == 1
{ "votes" : 2 }
> db.things.find({vote: {$gt: 2}}, {_id:0, votes:1}).limit(1) // current votes == 2
{ "votes" : 3 }
...

ご覧のとおり、スキップされた「投票」が等しいドキュメントが表示されます。そのため、ドキュメントを一意にし、等しい投票も繰り返す方法が必要です (Votes フィールドは頻繁に更新される可能性があり、すべてのドキュメントごとに多くの等しい値があります)。

この問題を解決する方法はありますか? ここにはある種の検索インデックスが必要なようです。しかし、私が言うように、条件フィールドは非常に頻繁に変更され、何百万ものドキュメントを計画しています。つまり、インデックスの更新は非常にコストのかかる操作であり、更新時にシステムの安全な応答が必要です。

4

1 に答える 1

0

結果がどのような順序で返されるかを気にしない場合は、それらを並べ替えてから_id、 を使用{$gt: current_id}して次の結果を取得する必要があります。

db.things.findOne({}, {votes: 1}).sort({_id: 1}) // _id == 0
db.things.findOne({_id: {$gt: 0}}, {votes: 1}).sort({_id: 1}) // _id == 1
db.things.findOne({_id: {$gt: 1}}, {votes: 1}).sort({_id: 1}) // _id == 2
...

で並べ替える必要がある場合は、代わりに次votesを使用する必要があります。skip

db.things.findOne({}, {votes: 1}).sort({votes: 1})
db.things.findOne({}, {votes: 1}).sort({votes: 1}).skip(1)
db.things.findOne({}, {votes: 1}).sort({votes: 1}).skip(2)
...

ただし、結果セットをさらにスキップする必要があるため、それは徐々に遅くなります。

于 2012-11-09T18:39:09.450 に答える