通配符索引限制
本页介绍了通配符索引的限制,例如不兼容的属性和不支持的查询模式。
复合通配符索引限制
复合通配符索引具有以下限制:
复合通配符索引只能有一个通配符。
示例,不能指定以下索引:
{ userID: 1, "object1.$**": 1, "object2.$**": 1 } compound wildcard index
中的非通配符术语必须是单键术语。 不允许使用多键术语。wildcardProjection
选项仅在通配符字段为$**
时有效。 为通配符索引术语指定字段路径(Field Path)时,不能使用wildcardProjection
。这是一个有效的定义:
{ key: { "$**": 1 }, name: "index_all_with_projection", wildcardProjection: { "someFields.name": 1, "otherFields.values": 1 } } 这是无效的定义:
{ key: { "someFields.$**": 1 }, name: "invalid_index", wildcardProjection: { "someFields.name": 1, "otherFields.values": 1 } } 默认情况下,
_id
字段被省略。 如果您需要_id
字段:将通配符索引指定为
$**
使用
wildcardProjection
指定
_id
字段
db.studentGrades.createIndex( { "$**": 1, }, { wildcardProjection: { _id: 1, exams: 1, extraCredit: 1 } } ) 通配符字段和常规字段不能包含相同的字段。 您可以使用
wildcardProjection
从通配符模式中排除字段。db.studentGrades.createIndex( { exams: 1, "$**": 1, homeworks: 1 }, { wildcardProjection: { exams: 0, homeworks: 0 } } )
不兼容的索引属性
不能为通配符索引指定以下属性:
不兼容的索引类型
不能使用通配符语法 ( $.**
) 创建以下索引类型:
片键
不能将通配符索引用作分片键索引。
不支持的查询模式
通配符索引不支持以下查询模式:
数组字段不等于 null
如果给定字段是集合中任何文档中的数组,则通配符索引不支持查询该字段不等于null
的文档。
例如,考虑一个inventory
集合,其通配符索引位于product_attributes
上。 如果product_attributes.tags
是集合中任何文档中的数组,则通配符索引不支持以下查询:
db.inventory.find( { $ne : [ "product_attributes.tags", null ] } ) db.inventory.aggregate( [ { $match : { $ne : [ "product_attributes.tags", null ] } } ] )
文档和数组上的相等匹配
通配符索引存储文档或大量内容的条目,而不是文档或大量本身。 因此,通配符索引不支持对文档或数组进行精确等值匹配。
示例,考虑一个inventory
集合,其通配符索引位于product_attributes
上。 通配符索引不支持以下查询:
db.inventory.find( { "product_attributes" : { "price" : 29.99 } } ) db.inventory.find( { "product_attributes.tags" : [ "waterproof", "fireproof" ] } )
注意
通配符索引可以支持字段等于空文档{}
的查询。
同样,通配符索引不支持对文档和数组进行精确的不等式匹配。 例如, product_attributes
上的通配符索引不能支持以下查询:
db.inventory.aggregate( [ { $match : { $ne : [ "product_attributes", { "price" : 29.99 } ] } } ] ) db.inventory.aggregate( [ { $match : { $ne : [ "product_attributes.tags", [ "waterproof", "fireproof" ] ] } } ] )
字段不存在
通配符索引比较稀疏,不会为空字段索引。 因此,通配符索引不支持查询不含字段的文档。
示例,考虑一个inventory
集合,其通配符索引位于product_attributes
上。 通配符索引不支持以下查询:
db.inventory.find( { "product_attributes" : { $exists : false } } ) db.inventory.aggregate( [ { $match : { "product_attributes" : { $exists : false } } } ] )
多字段查询谓词
通配符索引最多支持一个查询谓词字段。 这意味着:
MongoDB无法使用非通配符索引来支持查询谓词的一个部分,也无法使用通配符索引来支持另一部分。
MongoDB 无法使用多个通配符索引来支持同一查询中的不同谓词。
在单个通配符索引可以支持多个查询字段的情况下, MongoDB只能使用该通配符索引来支持其中一个查询字段。 MongoDB会根据相关的通配符索引路径自动选择支持通配符索引的字段。
示例,考虑一个inventory
集合,其通配符索引位于product_attributes
上。 通配符索引不能支持以下查询中的所有谓词:
db.inventory.find( { "product_attributes.price": { $gt: 20 }, "product_attributes.material": "silk", "product_attributes.size": "large" } )
相反, MongoDB使用通配符索引仅支持其中一个查询谓词。 MongoDB根据相关通配符索引路径选择支持哪些谓词。 不支持的查询谓词显示在rejectedPlans
解释结果 的 中。
使用排序查询
仅当 以下所有条件为sort()
true 时,MongoDB 才能使用通配符索引来满足 :
查询规划器选择通配符索引来满足查询谓词。
sort()
仅指定查询谓词字段。指定的字段绝不是数组。
如果不满足上述条件, MongoDB则无法使用通配符索引进行排序。 MongoDB不支持需要与查询谓词不同的索引的sort()
操作。
请考虑 products
集合的以下通配符索引:
db.products.createIndex( { "product_attributes.$**" : 1 } )
以下操作查询单个字段product_attributes.price
并对该字段进行排序:
db.products.find( { "product_attributes.price" : { $gt : 10.00 } }, ).sort( { "product_attributes.price" : 1 } )
假设指定的price
绝不是数组,则 MongoDB 可以使用product_attributes.$**
通配符索引来同时满足find()
和sort()
。