本页介绍了通配符索引的限制,例如不兼容的属性和不支持的查询模式。
复合通配符索引限制
复合通配符索引具有以下限制:
复合通配符索引只能有一个通配符。
示例,不能指定以下索引:
{ 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只能使用该通配符索引来支持其中一个查询字段。
示例,考虑一个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() 。