$exists 和 $in/nin 算作非前缀排序的相等查询吗?
Do $exists and $in/nin count as equality queries for non-prefix sorts?
指数
{ a: 1, b: 1, c: 1}
支持此查询:
db.data.find( { b: 3, a: 4 } ).sort( { c: 1 } )
是否也支持
db.data.find( { b: 3, a: {$exists: true} } ).sort( { c: 1 } )
db.data.find( { b: {$in: [3,4]}, a: 4 } ).sort( { c: 1 } )
db.data.find( { b: {$nin: [3,4]}, a: {$exists: false} } ).sort( { c: 1 } )
所有查询都将使用索引进行检索,但只有第二个用于排序,因为其他查询使用的运算符不是相等条件。
您可以通过 运行 使用 .explain()
的查询来证明这一点
请参阅下面这 3 个查询的解释(来自 MongoDB 2.6.3)的输出,省略了不必要的字段。 "cursor"
显示使用的索引,"indexBounds"
显示索引键的上下限。 "scanAndOrder" : false
表示索引也被用于排序
"indexBounds"
很重要,因为您可以看到相等条件 - 例如,请注意 "$exists" : false
是一个相等条件(为空)并且可能会在 "$exists" : true
时使用索引是一个范围。
另见 documentation on explain,它对于理解索引使用和诊断性能问题非常有用。
db.data.find( { b: 3, a: {$exists: true} } ).sort( { c: 1 } ).explain()
{
"cursor" : "BtreeCursor a_1_b_1_c_1",
"scanAndOrder" : true,
"indexBounds" : {
"a" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"b" : [
[
3,
3
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
}
,
db.data.find( { b: {$in: [3,4]}, a: 4 } ).sort( { c: 1 } ).explain()
{
"clauses" : [
{
"cursor" : "BtreeCursor a_1_b_1_c_1",
"scanAndOrder" : false,
"indexBounds" : {
"a" : [
[
4,
4
]
],
"b" : [
[
3,
3
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor a_1_b_1_c_1",
"scanAndOrder" : false,
"indexBounds" : {
"a" : [
[
4,
4
]
],
"b" : [
[
4,
4
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
],
}
,
db.data.find( { b: {$nin: [3,4]}, a: {$exists: false} } ).sort( { c: 1 } ).explain()
{
"cursor" : "BtreeCursor a_1_b_1_c_1",
"scanAndOrder" : true,
"indexBounds" : {
"a" : [
[
null,
null
]
],
"b" : [
[
{
"$minElement" : 1
},
3
],
[
3,
4
],
[
4,
{
"$maxElement" : 1
}
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
}
指数
{ a: 1, b: 1, c: 1}
支持此查询:
db.data.find( { b: 3, a: 4 } ).sort( { c: 1 } )
是否也支持
db.data.find( { b: 3, a: {$exists: true} } ).sort( { c: 1 } )
db.data.find( { b: {$in: [3,4]}, a: 4 } ).sort( { c: 1 } )
db.data.find( { b: {$nin: [3,4]}, a: {$exists: false} } ).sort( { c: 1 } )
所有查询都将使用索引进行检索,但只有第二个用于排序,因为其他查询使用的运算符不是相等条件。
您可以通过 运行 使用 .explain()
的查询来证明这一点请参阅下面这 3 个查询的解释(来自 MongoDB 2.6.3)的输出,省略了不必要的字段。 "cursor"
显示使用的索引,"indexBounds"
显示索引键的上下限。 "scanAndOrder" : false
表示索引也被用于排序
"indexBounds"
很重要,因为您可以看到相等条件 - 例如,请注意 "$exists" : false
是一个相等条件(为空)并且可能会在 "$exists" : true
时使用索引是一个范围。
另见 documentation on explain,它对于理解索引使用和诊断性能问题非常有用。
db.data.find( { b: 3, a: {$exists: true} } ).sort( { c: 1 } ).explain()
{
"cursor" : "BtreeCursor a_1_b_1_c_1",
"scanAndOrder" : true,
"indexBounds" : {
"a" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"b" : [
[
3,
3
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
}
,
db.data.find( { b: {$in: [3,4]}, a: 4 } ).sort( { c: 1 } ).explain()
{
"clauses" : [
{
"cursor" : "BtreeCursor a_1_b_1_c_1",
"scanAndOrder" : false,
"indexBounds" : {
"a" : [
[
4,
4
]
],
"b" : [
[
3,
3
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
},
{
"cursor" : "BtreeCursor a_1_b_1_c_1",
"scanAndOrder" : false,
"indexBounds" : {
"a" : [
[
4,
4
]
],
"b" : [
[
4,
4
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
],
}
,
db.data.find( { b: {$nin: [3,4]}, a: {$exists: false} } ).sort( { c: 1 } ).explain()
{
"cursor" : "BtreeCursor a_1_b_1_c_1",
"scanAndOrder" : true,
"indexBounds" : {
"a" : [
[
null,
null
]
],
"b" : [
[
{
"$minElement" : 1
},
3
],
[
3,
4
],
[
4,
{
"$maxElement" : 1
}
]
],
"c" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
}