实施社交游戏,其中每个个人资料可能会对其他个人资料提出许多挑战 每个挑战只有两个相关的配置文件,称为对手。
在我目前的架构设计中,我有挑战集合,每个文档看起来都像......
{
"_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}
事情是有一个开放的错误https://jira.mongodb.org/browse/SERVER-1205
这阻止了上述查询使用索引(因为$或和sort的组合)和查询非常慢。
是否有办法在保留当前架构时不使用$或运算符并使上述查询运行得更快?
所有这些问题让我想到我是否应该添加新的集合(让我们称之为 challenge_rel ),这会将每个配置文件与他的挑战联系起来(将挑战集合规范化一点)但似乎没有 - mongo方法不是吗?是否有更好的架构设计满足我的谦逊需求?
非常感谢您的回答!
答案 0 :(得分:1)
https://jira.mongodb.org/browse/SERVER-1205和https://jira.mongodb.org/browse/SERVER-3071。这应该直接帮助你。与此同时,如果您可以修改架构以将对手存储为数组,则可以将其作为索引查询执行。 我将上面的文档修改为
{
"_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"
}
]
}
我还用_id 3和4存储了2个其他文档,其中我更改了元素中的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"
}