Mongodb mongo查询如何包括;或;使用索引
这是一个当查询具有“或”时如何创建有效索引的问题。如果没有“或”,我知道如何创建有效的索引 这是我的问题Mongodb mongo查询如何包括;或;使用索引,mongodb,indexing,Mongodb,Indexing,这是一个当查询具有“或”时如何创建有效索引的问题。如果没有“或”,我知道如何创建有效的索引 这是我的问题 db.collection.find({ 'msg.sendTime':{$gt:1}, 'msg.msgType':{$in:["chat","g_card"]}, $or:[{'msg.recvId':{$in:['xm80049258']}},{'msg.userId':'xm80049258'}], $orderby:{'msg.sendTime'
db.collection.find({
'msg.sendTime':{$gt:1},
'msg.msgType':{$in:["chat","g_card"]},
$or:[{'msg.recvId':{$in:['xm80049258']}},{'msg.userId':'xm80049258'}],
$orderby:{'msg.sendTime':-1}})
在阅读了一些文章之后,我在msg.recvId和msg.userId上创建了两个单独的索引,这很有意义
$或查询的含义是:
- 在
find()
查询中,只能使用一个索引。因此,最好创建一个与查询中的字段对齐的索引。否则,MongoDB将执行集合扫描
- 除非查询是
$或
查询,否则MongoDB可以为每个$或术语使用一个索引
- 总之,如果查询中有
$或,最好将$或术语作为顶级术语,并分别为每个术语创建索引
所以要回答你的问题:
我想知道mongodb在什么时候执行“或”,它是否首先分割所有文档,然后使用msg.sendTime和msg.msgType
如果您的查询有一个顶级$或子句,MongoDB可以为每个子句使用一个索引。否则,它将执行收集扫描或半收集扫描。例如,如果您有索引:
db.collection.createIndex({a: 1, b: 1})
您可以创建两种常规类型的查询:
1. <代码>$或
不在查询的顶层
此查询可以使用索引,但不会执行:
db.collection.find({a: 1, $or: [{b: 1}, {b: 2}]})
由于查询的explain()
输出为:
> db.collection.explain().find({a: 1, $or: [{b: 1}, {b: 2}]})
{
"queryPlanner": {
...
"indexBounds": {
"a": [
"[1.0, 1.0]"
],
"b": [
"[MinKey, MaxKey]"
]
...
请注意,查询计划器无法使用b
字段的适当边界,因为它正在执行半收集扫描(因为它正在从MinKey
到MaxKey
搜索b
,即所有内容)。上面的查询计划器结果基本上是这样的:“查找a=1
的文档,并扫描所有文档,查找值为1
或2
的b
”
2. <查询顶层的code>$或
但是,将$或
子句拉到顶层:
db.collection.find({$or: [{a: 1, b: 1}, {a: 1, b: 2}]})
将生成此查询计划:
> db.test.explain().find({$or: [{a: 1, b: 1}, {a: 1, b: 2}]})
{
"queryPlanner": {
...
"winningPlan": {
"stage": "SUBPLAN",
...
"inputStages": [
{
"stage": "IXSCAN",
...
"indexBounds": {
"a": [
"[1.0, 1.0]"
],
"b": [
"[1.0, 1.0]"
]
}
},
{
"stage": "IXSCAN",
...
"indexBounds": {
"a": [
"[1.0, 1.0]"
],
"b": [
"[2.0, 2.0]"
]
请注意,$或
的每个术语都被视为一个单独的查询,每个查询都有一个严格的边界。因此,上面的查询计划是这样的:“查找a=1、b=1或a=1、b=2的文档”
。可以想象,与前面的查询相比,此查询的性能要高得多
关于第二个问题:
在这种情况下,如何创建有效的索引?我应该创建索引(msg.sendTime:1,msg.msgType:1,msg.recvId:1)和(msg.sendTime:1,msg.msgType:1,msg.userId:1)
如上所述,您需要将适当的查询与适当的索引结合起来以获得最佳结果。MongoDB可以使用您建议的两个索引,如果您重新安排查询,使$或位于查询的顶层,那么这两个索引将最有效
我鼓励您了解MongoDB的explain()
输出,因为它是确定查询是否使用正确索引的最佳工具
您可能会发现有用的相关资源包括:
看一看,然后看一看查询结果(并调整它,看看解释是如何变化的),我这样做的。但是我想知道mongo是如何分析查询包含“or”的,而不是为这个查询找到合适的索引的。而OrderBy最终总是发生在任何数据库中。非常感谢,@lovegupta。我明天会试试,:)找到另一件事:。与你分享。