1

各プロファイルが他のプロファイルと多くの課題を持つことができるソーシャル ゲームを実装します。各チャレンジには、対戦相手
と呼ばれる関連するプロファイルが 2 つだけあります。

私の現在のスキーマ設計では、各ドキュメントが次のように見える課題コレクションがあります...

{
"_id" : ObjectId("51e8de5be4b0131df7db33c6"),
"state" : "ACTIVE",
"move" : "b0fe109d9663a87e8450ed1299ae8927",
"creationTime" : ISODate("2013-07-19T06:36:11.228Z"),
"lastUpdateTime" : ISODate("2013-07-19T11:18:44.856Z"),
"round" : 1,
"opponent1" : {
     "pid" : "b0fe109d9663a87e8450ed1299ae8927",
     "firstName" : "",
     "lastName" : "",
     "imageUrl" : "",
     "unique" : "",
     "gender" : "male"
},
"opponent2" : {
     "pid" : "4fc84459576623099eeb96329c1243de",
     "firstName" : "",
     "lastName" : "",
     "imageUrl" : "",
     "unique" : "",
     "gender" : "male"
}

チャレンジは誰がリクエストしているかに関してステートレスです。つまり、相手 1 と相手 2 は同じドキュメントを取得します。

特定のプロファイル チャレンジを取得する場合は、$or演算子を使用しています

Query:{ "$or" : [ { "opponent1.pid" : "profileID"} , { "opponent2.pid" : "profileID"}]}
Sort:{ "lastUpdateTime" : -1}

次のようにネストされたインデックスがあります

{ "opponent1.pid":1}
{ "opponent2.pid":1}

問題は、未解決のバグhttps://jira.mongodb.org/browse/SERVER-1205
があり、上記のクエリでインデックスを使用できない ($or と sort の組み合わせのため) ことと、クエリが非常に遅いことです。 .

現在のスキーマに残っている間に $or 演算子を使用せず、上記のクエリをより高速に実行する方法はありますか?

このすべての問題により、新しいコレクションを追加する必要があるかどうかを考えさせられました ( challenge_relと呼びましょう)。これは、各プロファイルを彼の課題に関連付けます (課題コレクションを少し正規化します)。私の謙虚なニーズに適したスキーマ設計はありますか?

あなたの答えは大歓迎です!

4

1 に答える 1

1

https://jira.mongodb.org/browse/SERVER-1205およびhttps://jira.mongodb.org/browse/SERVER-3071は、MongoDB 2.5.x (2.6 リリース バージョン) で修正される予定です。それはあなたを直接助けるはずです。それまでの間、対戦相手を配列として格納するようにスキーマを変更できる場合は、これをインデックス付きクエリとして実行できます。上記のドキュメントを次のように変更しました

{
        "_id" : 1,
        "state" : "ACTIVE",
        "move" : "b0fe109d9663a87e8450ed1299ae8927",
        "creationTime" : ISODate("2013-07-19T06:36:11.228Z"),
        "lastUpdateTime" : ISODate("2013-07-19T11:18:44.856Z"),
        "round" : 1,
        "opponents" : [
        {
                "pid" : "b0fe109d9663a87e8450ed1299ae8927",
                "firstName" : "",
                "lastName" : "",
                "imageUrl" : "",
                "unique" : "",
                "gender" : "male"
        },
        {
                "pid" : "4fc84459576623099eeb96329c1243de",
                "firstName" : "",
                "lastName" : "",
                "imageUrl" : "",
                "unique" : "",
                "gender" : "male"
        }
        ]
}

また、要素の pid を変更した _id 3 と 4 の 2 つのドキュメントを保存しました (実際に or を実行することを証明するため)。クエリはインデックスを使用するようになりました

> db.foo.find({"opponents.pid":{$in:["b0fe109d9663a87e8450ed1299ae8927", "4fc844
59576623099eeb96329c1243de"]}}).sort({lastUpdateTime:-1}).explain()
{
        "cursor" : "BtreeCursor opponents.pid_1_lastUpdateTime_-1 multi",
        "isMultiKey" : true,
        "n" : 3,
        "nscannedObjects" : 4,
        "nscanned" : 4,
        "nscannedObjectsAllPlans" : 8,
        "nscannedAllPlans" : 8,
        "scanAndOrder" : true,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 0,
        "indexBounds" : {
                "opponents.pid" : [
                        [
                                "4fc84459576623099eeb96329c1243de",
                                "4fc84459576623099eeb96329c1243de"
                        ],
                        [
                                "b0fe109d9663a87e8450ed1299ae8927",
                                "b0fe109d9663a87e8450ed1299ae8927"
                        ]
                ],
                "lastUpdateTime" : [
                        [
                                {
                                        "$maxElement" : 1
                                },
                                {
                                        "$minElement" : 1
                                }
                        ]
                ]
        },
        "server" : "sridhar-PC:27017"
}
于 2013-07-19T22:10:03.340 に答える