18

最大 100,000 人の友人を持つ以下の競合するスキーマを考えると、私のニーズに最も効率的なものを見つけることに興味があります。

Doc1 (user_id のインデックス)

{
"_id" : "…",
"user_id" : "1",
friends : {
    "2" : {
        "id" : "2",
        "mutuals" : 3
    }
     "3" : {
         "id" : "3",
         "mutuals": "1"
    }
   "4" : {
         "id" : "4",
         "mutuals": "5"
    }
}
}

Doc2 (user_id と friends.id の複合マルチキー インデックス)

{
"_id" : "…",
"user_id" : "1",
friends : [
   {
        "id" : "2",
        "mutuals" : 3
    },
    {
         "id" : "3",
         "mutuals": "1"
    },
   {
         "id" : "4",
         "mutuals": "5"
    }
]}

サブフィールド検索の効率に関する情報が見つからないようです。mongo はデータを BSON として内部的に実装していることを知っているので、射影ルックアップがバイナリ O(log n) であることを意味するかどうか疑問に思っています。

具体的には、friend_id を持つ友人が存在するかどうかを調べるための user_id が与えられた場合、各スキーマに対する 2 つの異なるクエリはどのように比較されるでしょうか? (上記のインデックスを想定) 何が返されるかは問題ではなく、フレンドが存在する場合に null 以外が返されることに注意してください。

Doc1col.find({user_id : "…"}, {"friends.friend_id"})
Doc2col.find({user_id : "…", "friends.id" : "friend_id"}, {"_id":1})

$set 修飾子がどのように機能するかも興味深いです。スキーマ 1 の場合、クエリが与えられた場合Doc1col.update({user_id : "…"}, {"$set" : {"friends.friend_id.mutuals" : 5})、friends.friend_id のルックアップはどのように機能しますか? これは O(log n) 操作ですか (n は友達の数)?

スキーマ 2 の場合、クエリは上記のクエリとどのようにDoc2col.update({user_id : "…", "friends.id" : "friend_id"}, {"$set": {"friends.$.mutuals" : 5})比較されますか?

4

1 に答える 1

3

doc1 は、主な要件が管理しやすいパッケージでデータを UI に提示することである場合に適しています。プロジェクションを使用して目的のデータのみを簡単にフィルタリングできます{}, {friends.2 : 1}

ユースケースは結果を気にしないため、doc2 が最も一致します。何が返されるかは問題ではなく、インデックスを作成するとフェッチが高速化されることに注意してください。

その上、doc2 はよりクリーンな構文を許可します

db.doc2.findOne({user_id: 1, friends.id : 2} )

db.doc1.findOne({ $and : [{ user_id: 1 }, { "friends.2" : {$exists: true} }] })

ただし、最後に、doc1 にスパース インデックスを作成 (および $exists を使用) することはできますが、100,000 人の友達がいる可能性 (各友達にはスパース インデックスが必要) を考えると、それはばかげています。合理的な数のエントリとは対照的に、人口統計の性別[男性、女性]、年齢層[0-10、11-16、25-30、..]、またはそれ以上の意味のあるもの[ジン、ウィスキー、ウォッカ、...]

于 2014-12-01T03:02:34.963 に答える