2013-07-19 30 views
1

實現一個社會的遊戲,每個配置文件可以與其它型材許多挑戰。
每一個挑戰只有兩個相關的配置文件名爲對手

在我目前的架構設計,我有挑戰集合中的每個文件看起來像是......

{ 
"_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" 
} 

面臨的挑戰是無狀態的關於向誰請求它,這意味着opponent1和opponent2會得到相同的文件。

當我想找回我使用$或操作

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

我有嵌套指標的特定配置文件挑戰如下

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

的事情是,有一個開放的bug https://jira.mongodb.org/browse/SERVER-1205
從上面的查詢防止使用索引(因爲$或和排序的組合)和查詢非常SL流。

有沒有辦法不使用$或運營商在當前模式中剩餘的同時,讓上面的查詢運行得更快?

這一切問題讓我思考我是否應該添加新的集合(可以稱之爲challenges_rel),這將涉及每個配置文件到他的挑戰(正常化的挑戰收集了一下),但它似乎未蒙戈方法ISN是嗎?對我的卑微需求有沒有更好的模式設計?

你的答案是高度讚賞!

+0

您是否嘗試過做兩個查詢(實際上是MongoDB中做什麼)和合並的結果在您的應用索引? –

+0

您發現僅在子文檔,排序總是躲躲閃閃的,當你做它一個多值字段 – Sammaye

+0

@Sammaye事情是錯誤是不相關的子文件它是$或和排序組合..如果我不要把結果全部分好。 –

回答

1

https://jira.mongodb.org/browse/SERVER-1205https://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" 
     } 
     ] 
} 

我也存儲其它2個文檔與_id 3和4其中I中的元素改變了PID(以證明它實際上的或)。 現在查詢使用

> 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" 
} 
+0

只是要寫我的問題相同的答案,但你早些時候回答:) btw在你的解釋「scanAndOrder」:真正的意味着排序不使用索引...只是爲了讓你知道..無論如何謝謝。 –