2011-01-26 18 views
2

私が取り組んでいるアプリケーションでは、10〜1,000,000アイテム程度の大規模なセット交差を行う必要があります。私たちが交差しているアイテムは単にObjectIdです。mongodbのサーバーサイドセット交差点

たとえばボックス文書があり、ボックス文書の中にitem_ids配列があります。各ボックスのこのitem_ids配列には、10〜1,000,000個のObjectIdが格納されます。

ここで最終目標は、ObjectId 4d3dc3898951498107000005のボックスAと、ObjectId 4d3dc3898951498107000002のボックスB(item_idsは共通)です。ここで

はイムはそれをやってどのようである:これはまともなアプローチのように思える場合

db.boxes.distinct("item_ids", {'_id' : {$in : [ObjectId("4d3dc3898951498107000005"), ObjectId("4d3dc3898951498107000002")]}}) 

まず好奇心。私の研究では、map reduceは大規模な交差点の一般的な提案ですが、リアルタイムクエリには推奨されません。

第2に、これがシャード環境でどのように動作するのか不思議ですか? mongosはそれが必要とするmongodに関する質問の塊を実行し、私の結果を魔法のように集めるのだろうか?

最後に、正気である上記の場合は、行うことは、それはまた、正気です:

基本的にボックスAとボックスBの両方に共通しているどのアイテム探し、その後、オブジェクトのすべてにそれらを実体化されるだろう
db.items.find({'_id' : { $in : db.eval(function() {return db.boxes.distinct("item_ids", {_id:{$in:[ObjectId("4d3dc3898951498107000005"), ObjectId("4d3dc3898951498107000002")]}}); }) }}) 

1つのサーバー側のクエリで。これは、データセットのページングを効果的に実装するために、.limitと.skipを使用しているようにも見えます。

いずれにしても、フィードバックは貴重です。ありがとうございます!

+0

共通の値を見つけるために「別個の」方法はどのようになっていますか?これは、 "コレクション内の特定のキーの個別の値のリストを返します"。 Distinctには 'intersection'機能がありません。これはAまたはBにあるすべてのIdのリストを提供します。あるいは、 'union'を意味しますか? –

+0

オイ、ええ、あなたは正しいです。私は明らかにもっとコーヒーが必要です。私はこの質問を削除する必要があります。サーバー側配列/セット交差点のための他のアイデアがある場合に備えて、ちょっと残しておきます。ありがとう! – spotman

答えて

3

あなたのスキーマを再検討したいと思うかもしれません。 ObjectIDの配列がそれぞれ12バイトで1,000,000個ある場合は、BSONのオーバヘッドをカウントしていないものもあります。これは大規模な配列*(おそらく別の8 MB程度)で重要になります。 1.8では最大ドキュメントサイズを4MBから16MBに引き上げていますが、保存しようとしているオブジェクトではそれでは十分ではありません。

※歴史上の理由から、<要素が100個の場合は問題なく、6桁または7桁の数字が必要な場合は追加されます。

+0

ええ、私はあなたが正しいと思います。 mongoの特徴を活かして、よりうまくいくかもしれないスキーマのアイデア?私はモンゴーに少し新しく、まだ生産に大きなものは何も持っていません。私が考えたアプローチの1つは、アイテムがどのボックスに入っているのか、IE box_itemsなのかなどを記述した文書を持っている可能性があります。しかし、これはrdbmsのように感じ始め、たくさんの小さな文書を作成します。しかし、ItemとBoxはこのアプリケーションではファーストクラスのクラスであり、どちらもmongoのスキーマの柔軟性を最大限に活用しています。 rdbmsを使用すると、バックトラッキングのように感じることができます。( – spotman

+0

あなたのアプリケーションについて詳しく知ることなくスキーマのアドバイスを提供するのは難しいです。mongodb-メーリングリストmongodb-mail @ googlegroups.com – mstearn