質問

Mongodbにネストされたセット(コメントの木など)を保存するためのベストプラクティスは何ですか?

つまり、すべてのコメントには、親のコメントと子供のコメント(回答)があります。

このように保管する:

{
   title: "Hello",
   body: "Please comment me!",
   comments: [
        {
            author: "Peter",
            text: "Hi there",
            answers: [
                  {
                      author: "Peter",
                      text: "Hi there",
                      answers: [
                                 { author: "Ivan", text: "Hi there" },
                                 { author: "Nicholas", text: "Hi there" }
                      ]
                  },
                  { author: "Ivan", text: "Hi there" },
                  { author: "Nicholas", text: "Hi there" },
            ]
        },
        { author: "Ivan", text: "Hi there" },
        { author: "Nicholas", text: "Hi there" },
   ]
}

たとえば、「ピーターによってコメントされているすべての投稿」をマップ/削減せずに求めることはできないため、クールではありません。

役に立ちましたか?

解決

完璧な解決策はないと思います - アプリにとってどの操作がより重要であるかによって異なります。たとえば、Mongodbにネストされたコメントのコメントがシリコンアレイインサイダーコメントだと思います。それはあなたが言及するクエリをより難しくします。

1つのオプションは、アレイ内のすべてのコメンターのリストを投稿のトップレベルに保存することです。それは非正規化データと考えてください。その後、特定のコメンターを含むすべての投稿を簡単に見つけることができます。次に、ドリルダウンするには、Map/Reduceまたはdb.eval()を使用して、ネストされた投稿情報を内部に取得します。

もう1つのメモ - 単一のドキュメントを扱っている場合、db.eval()はおそらくMAP/reduceよりも軽量です。 $もオプションですが、遅いこともあるので、上記の追加の「コメンターのリスト」が好きです - その配列も簡単にインデックスすることはできません(ドキュメントの「マルチケイ」を参照)。

参照:http://groups.google.com/group/mongodb-user/browse_thread/thread/df8250573c91f75a/e880d9c57e343b52?lnk=gst&q=TreeS#E880D9C57E343B52

他のヒント

DMのポストDwight Merrimanのリンクでは、パスキーを使用してRegex Matchesを実行することに言及しています

{
  path : "a.b.c.d.e.f"
}

これを行う別の方法は、配列を使用することです

{
  path : ["a", "b", "c", "d", "e", "f"]
}

db.test.ensureIndex({path: 1})

それはかなり速くなるはずです。

各ノードが単一のパスにしかない場合、リスト内の場所について心配する必要はありません

db.test.find({path: "a"})

「A」のすべての子供を見つけるでしょう

パス名の代わりに、おそらくノードの_idを使用します。

アップデート

  • 注意すべきことの1つは、インデックスに1つの配列しか持てないことです。
  • クエリで説明するように注意してください

    db.test.find({path:{$ in:["a"、 "b"]})

あなたにあげる

 db.test.find({path: {$in: ["a", "b"]}}).explain()
{
        "cursor" : "BtreeCursor path_1 multi",
        "nscanned" : 2,
        "nscannedObjects" : 2,
        "n" : 1,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : true,
        "indexOnly" : false,
        "indexBounds" : {
                "path" : [
                        [
                                "a",
                                "a"
                        ],
                        [
                                "b",
                                "b"
                        ]
                ]
        }
}

しかし

 db.test.find({path: {$all: ["a", "b"]}}).explain()
{
        "cursor" : "BtreeCursor path_1",
        "nscanned" : 1,
        "nscannedObjects" : 1,
        "n" : 1,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : true,
        "indexOnly" : false,
        "indexBounds" : {
                "path" : [
                        [
                                "a",
                                "a"
                        ]
                ]
        }
}

最初の要素のみを使用し、bのすべてのマッチング結果をスキャンします。
Aがあなたのルート要素であるか、ほとんどのレコードにある場合、効率的なインデックスクエリではなく、レコードをほぼ完全にスキャンしています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top