假设我有一个类似这样的文档:
{
_id: ObjectId("5260ca3a1606ed3e76bf3835"),
event_id: "20131020_NFL_SF_TEN",
team: {
away: "SF",
home: "TEN"
}
}
我想查询任何以“SF”作为客队或主队的比赛。所以我在team.away
和team.home
上放了一个索引并运行$或查询以查找所有旧金山游戏。
另一种选择:
{
_id: ObjectId("5260ca3a1606ed3e76bf3835"),
event_id: "20131020_NFL_SF_TEN",
team: [
{
name: "SF",
loc: "AWAY"
},
{
name: "TEN",
loc: "HOME"
}
]
}
在上面的数组中,我可以像以前一样在team.name
而不是两个索引上放置一个索引。然后我会查询team.name
里面有“SF”的游戏。
哪种查询会更有效率?谢谢!
答案 0 :(得分:2)
我相信您会想要使用您在team.name
上使用单个索引的第二个示例。
使用$or
运算符时,您需要了解一些特殊注意事项。引用documentation(带有一些额外的格式):
使用带
$or
个查询的索引时,请记住$or
查询的每个子句将并行执行。这些子句都可以使用自己的索引。
db.inventory.find ( { $or: [ { price: 1.99 }, { sale: true } ] } )
对于此查询,您将在价格上创建一个索引:
db.inventory.ensureIndex({ price: 1 }
,
和另一个销售指数:db.inventory.ensureIndex({ sale: 1 } )
而不是复合指数。
考虑到您的第一个示例,索引您不打算专门查询的字段没有多大意义。当你说你不介意{/ 1}}正在客场比赛或主场比赛中进行比赛时,你会始终包括SF
和您的查询中包含away
个字段,因此您使用的是两个索引,其中您需要查询的只有一个值 - home
。
在此阶段提及您在考虑文档格式时应始终考虑大部分查询。考虑一下您计划最常进行的查询并相应地构建文档。最好尽可能地处理80%的案例,而不是试图解决所有可能性(这可能会导致整体性能下降)。
看看你的第二个例子,如你所说的嵌套文档,你只需要使用一个索引(节省服务器上的宝贵空间)。
来自$or
docs的一些更相关的引用(再次添加格式):
此外,在查询中使用
SF
运算符和$or
方法时,查询将不会使用sort()
字段上的索引。考虑以下查询将$or
方法添加到上述查询中:
sort()
此修改后的查询不会使用
db.inventory.find ({ $or: [{ price: 1.99 }, { sale: true }] }).sort({item:1})
上的索引,也不会使用price
上的索引。
现在的问题是 - 你打算使用sale
功能吗?如果答案是肯定的,那么你应该知道你的索引可能会变得毫无用处! :(
从这里拿走就是“它取决于!”。考虑您计划进行的查询,并根据您的使用情况预测,考虑哪些文档结构和索引对您最有利。