索引交集¶
2.6 新版功能.
MongoDB使用多个索引的交集来匹配查询. [1] 一般每个索引交集会涉及两个索引, 但是MongoDB也可以使用多个索引或者嵌套索引的交集来解决一个查询.
下面的例子会演示索引交集的使用, 假设集合 orders 有如下索引:
{ qty: 1 }
{ item: 1 }
MongoDB可以使用这两个索引的交集来支持如下的查询:
db.orders.find( { item: "abc123", qty: { $gt: 15 } } )
如果一个查询计划(query plan)使用了索引交集, 方法 explain() 返回的文档的 cursor 键的值将会是 Complex Plan .
[1] | 在以前的版本, MongoDB只能使用一条索引来尽可能地匹配查询. 有一个例外情况是带有 $or 的语句, 这时查询会为每个 $or 条件使用一条索引. |
索引前缀交集¶
MongoDB可以使用整个索引或者索引的前缀部分作交集. 索引的前缀是指复合索引键的一个子集, 由从索引的第一个键开始的一个或多个键组成.
假设集合 orders 有如下索引:
{ qty: 1 }
{ status: 1, ord_date: -1 }
为了能匹配下面这个同时指定了 qty 键和 status 键的查询, MongoDB可以使用这两个索引的交集来匹配这个查询:
db.orders.find( { qty: { $gt: 10 } , status: "A" } )
索引交集和复合索引¶
索引前缀并不会消除对 复合索引 的需要. 但是, 由于排列顺序(例如, 索引中键的排布顺序)和排序顺序(例如, 递增/递减)这些因素在 复合索引 中很重要,一个复合索引可能无法支持一个不包含 该索引的前缀键 的查询或者指定了一个不同排序顺序的查询.
例如, 如果集合 orders 有如下复合索引, 其中 status 键在 ord_date 键的前面:
{ status: 1, ord_date: -1 }
那么复合索引可以支持如下查询:
db.orders.find( { status: { $in: ["A", "P" ] } } )
db.orders.find(
{
ord_date: { $gt: new Date("2014-02-01") },
status: {$in:[ "P", "A" ] }
}
)
但是, 下面的这两条查询就不会被支持了:
db.orders.find( { ord_date: { $gt: new Date("2014-02-01") } } )
db.orders.find( { } ).sort( { ord_date: 1 } )
相反, 如果一个集合有两条不同的索引如下:
{ status: 1 }
{ ord_date: -1 }
那么, 这两个索引可以支持上述四条索引, 以单一索引的方式或者以两条索引的交集的方式.
创建能正好匹配您的查询的复合索引还是依赖索引交集, 这取决于您的系统的具体情况.
参见
索引交集和排序¶
当 sort() 方法需要的索引无法匹配查询条件(或者部分查询条件)时, 索引交集将不会被采用.
例如, 集合 orders 有如下索引:
{ qty: 1 }
{ status: 1, ord_date: -1 }
{ status: 1 }
{ ord_date: -1 }
MongoDB无法使用索引交集来匹配如下查询并排序:
db.orders.find( { qty: { $gt: 10 } } ).sort( { status: 1 } )
因为, MongoDB无法使用索引 { qty: 1 } 来匹配查询条件, 却使用与之完全不同的 { status: 1 } 或者 { status: 1, ord_date: -1 } 索引来排序.
但是, MongoDB可以使用索引交集来匹配如下查询并排序, 因为索引 { status: 1, ord_date: -1 } 可以匹配部分查询条件.
db.orders.find( { qty: { $gt: 10 } , status: "A" } ).sort( { ord_date: -1 } )