On this page本页内容
MongoDB supports creating indexes on a field or set of fields to support queries. MongoDB支持在字段或字段集上创建索引以支持查询。Since MongoDB supports dynamic schemas, applications can query against fields whose names cannot be known in advance or are arbitrary.由于MongoDB支持动态模式,应用程序可以查询名称无法预先知道或任意的字段。
New in version MongoDB: 4.2在版本4.2中新增
MongoDB 4.2 introduces wildcard indexes for supporting queries against unknown or arbitrary fields.MongoDB 4.2引入了通配符索引,用于支持对未知或任意字段的查询。
Consider an application that captures user-defined data under the 考虑一个在userMetadata
field and supports querying against that data:userMetadata
字段下捕获用户定义数据并支持对该数据进行查询的应用程序:
{ "userMetadata" : { "likes" : [ "dogs", "cats" ] } } { "userMetadata" : { "dislikes" : "pickles" } } { "userMetadata" : { "age" : 45 } } { "userMetadata" : "inactive" }
Administrators want to create indexes to support queries on any subfield of 管理员希望创建索引以支持对userMetadata
.userMetadata
的任何子字段的查询。
A wildcard index on userMetadata
can support single-field queries on userMetadata
, userMetadata.likes
, userMetadata.dislikes
, and userMetadata.age
:userMetadata
上的通配符索引可以支持对userMetadata
、userMetadata.likes
、userMetadata.dislikes
和userMetadata.age
的单字段查询:
db.userData.createIndex( { "userMetadata.$**" : 1 } )
The index can support the following queries:索引可以支持以下查询:
db.userData.find({ "userMetadata.likes" : "dogs" }) db.userData.find({ "userMetadata.dislikes" : "pickles" }) db.userData.find({ "userMetadata.age" : { $gt : 30 } }) db.userData.find({ "userMetadata" : "inactive" })
A non-wildcard index on userMetadata
can only support queries on values of userMetadata
.userMetadata
上的非通配符索引只能支持对userMetadata
值的查询。
Wildcard indexes are not designed to replace workload-based index planning. 通配符索引不是为了取代基于工作负载的索引规划而设计的。For more information on creating indexes to support queries, see Create Indexes to Support Your Queries. 有关创建索引以支持查询的更多信息,请参阅创建索引以支撑查询。For complete documentation on wildcard index limitations, see Wildcard Index Restrictions.有关通配符索引限制的完整文档,请参阅通配符索引限制。
The mongod
featureCompatibilityVersion must be 4.2
to create wildcard indexes. mongod
featureCompatibilityVersion
必须为4.2才能创建通配符索引。For instructions on setting the fCV, see Set Feature Compatibility Version on MongoDB 5.0 Deployments.有关设置fCV的说明,请参阅在MongoDB 5.0部署上设置功能兼容性版本。
You can create wildcard indexes using the 您可以使用createIndexes
database command or its shell helpers, createIndex()
or createIndexes()
.createIndexes
数据库命令或其shell助手createIndex()
或createIndexes()
创建通配符索引。
To index the value of a specific field:要索引特定字段的值,请执行以下操作:
db.collection.createIndex( { "fieldA.$**" : 1 } )
With this wildcard index, MongoDB indexes all values of 通过这个通配符索引,MongoDB对fieldA
. fieldA
的所有值进行索引。If the field is a nested document or array, the wildcard index recurses into the document/array and stores the value for all fields in the document/array.如果字段是嵌套文档或数组,则通配符索引将递归到文档/数组中,并存储文档/数组内所有字段的值。
For example, documents in the 例如,product_catalog
collection may contain a product_attributes
field. product_catalog
集合中的文档可能包含product_attributes
字段。The product_attributes
field can contain arbitrary nested fields, including embedded documents and arrays:product_attributes
字段可以包含任意嵌套字段,包括嵌入式文档和数组:
{ "product_name" : "Spy Coat", "product_attributes" : { "material" : [ "Tweed", "Wool", "Leather" ] "size" : { "length" : 72, "units" : "inches" } } } { "product_name" : "Spy Pen", "product_attributes" : { "colors" : [ "Blue", "Black" ], "secret_feature" : { "name" : "laser", "power" : "1000", "units" : "watts", } } }
The following operation creates a wildcard index on the 以下操作在product_attributes
field:product_attributes
字段上创建通配符索引:
db.products_catalog.createIndex( { "product_attributes.$**" : 1 } )
The wildcard index can support arbitrary single-field queries on 通配符索引可以支持对product_attributes
or its embedded fields:product_attributes
或其嵌入字段的任意单字段查询:
db.products_catalog.find( { "product_attributes.size.length" : { $gt : 60 } } ) db.products_catalog.find( { "product_attributes.material" : "Leather" } ) db.products_catalog.find( { "product_attributes.secret_feature.name" : "laser" } )
The path-specific wildcard index syntax is incompatible with the 路径特定的通配符索引语法与wildcardProjection
option. wildcardProjection
选项不兼容。See the Options for 有关更多信息,请参阅通配符索引选项。wildcard
indexes for more information.
For an example, see Create a Wildcard Index on a Single Field Path.有关示例,请参阅在单个字段路径上创建通配符索引。
To index the value of all fields in a document (excluding 要索引文档中所有字段的值(不包括_id
), specify "$**"
as the index key:_id
),请指定"$**"
作为索引键:
db.collection.createIndex( { "$**" : 1 } )
With this wildcard index, MongoDB indexes all fields for each document in the collection. 使用此通配符索引,MongoDB为集合中每个文档的所有字段编制索引。If a given field is a nested document or array, the wildcard index recurses into the document/array and stores the value for all fields in the document/array.如果给定字段是嵌套文档或数组,则通配符索引将递归到文档/数组中,并存储文档/数组内所有字段的值。
For an example, see Create a Wildcard Index on All Field Paths.有关示例,请参阅在所有字段路径上创建通配符索引。
Wildcard indexes omit the 默认情况下,通配符索引省略_id
field by default. _id
字段。To include the 要在通配符索引中包含_id
field in the wildcard index, you must explicitly include it in the wildcardProjection
document. _id
字段,必须在wildcardProjection
文档中显式包含它。See Options for 有关详细信息,请参阅通配符索引选项。wildcard
indexes for more information.
To index the values of multiple specific fields in a document:要索引文档中多个特定字段的值,请执行以下操作:
db.collection.createIndex( { "$**" : 1 }, { "wildcardProjection" : { "fieldA" : 1, "fieldB.fieldC" : 1 } } )
With this wildcard index, MongoDB indexes all values for the specified fields for each document in the collection. 使用此通配符索引,MongoDB为集合中每个文档的指定字段的所有值编制索引。If a given field is a nested document or array, the wildcard index recurses into the document/array and stores the value for all fields in the document/array.如果给定字段是嵌套文档或数组,则通配符索引将递归到文档/数组中,并存储文档/数组内所有字段的值。
Wildcard indexes do not support mixing inclusion and exclusion statements in the 通配符索引不支持在wildcardProjection
document except when explicitly including the _id
field. wildcardProjection
文档中混合包含语句和排除语句,除非显式包含_id
字段。For more information on 有关wildcardProjection
, see the Options for wildcard
indexes.wildcardProjection
的更多信息,请参阅通配符索引选项。
For an example, see Include Specific Fields in Wildcard Index Coverage.有关示例,请参阅在通配符索引覆盖率中包含特定字段。
To index the fields of all fields in a document excluding specific field paths:要对文档中除特定字段路径之外的所有字段的字段进行索引,请执行以下操作:
db.collection.createIndex( { "$**" : 1 }, { "wildcardProjection" : { "fieldA" : 0, "fieldB.fieldC" : 0 } } )
With this wildcard index, MongoDB indexes all fields for each document in the collection excluding the specified field paths. 使用此通配符索引,MongoDB为集合中每个文档的所有字段编制索引,不包括指定的字段路径。If a given field is a nested document or array, the wildcard index recurses into the document/array and stores the values for all fields in the document/array.如果给定字段是嵌套文档或数组,则通配符索引将递归到文档/数组中,并存储文档/数组内所有字段的值。
For an example, see Omit Specific Fields from Wildcard Index Coverage.有关示例,请参阅从通配符索引覆盖率中省略特定字段。
Wildcard indexes do not support mixing inclusion and exclusion statements in the 通配符索引不支持在wildcardProjection
document except when explicitly including the _id
field. wildcardProjection
文档中混合包含和排除语句,除非显式包含_id
字段。For more information on 有关wildcardProjection
, see the Options for wildcard
indexes.wildcardProjection
的更多信息,请参阅通配符索引选项。
mongod
featureCompatibilityVersion must be 4.2
to create wildcard indexes. mongod
featureCompatibilityVersion必须为4.2
才能创建通配符索引。_id
field in the wildcard index, you must explicitly include it in the wildcardProjection document (i.e. { "_id" : 1 }
)._id
字段,必须在通配器投影文档中显式包含它(即{ "_id" : 1 }
)。Wildcard indexes have specific behavior when indexing fields which are an object (i.e. an embedded document) or an array:当索引作为对象(即嵌入文档)或数组的字段时,通配符索引具有特定的行为:
If the field is an array, then the wildcard index traverses the array and indexes each element:如果字段是数组,则通配符索引遍历数组并为每个元素编制索引:
The wildcard index continues traversing any additional nested objects or arrays until it reaches a primitive value (i.e. a field that is not an object or array). 通配符索引继续遍历任何其他嵌套对象或数组,直到它达到原始值(即,不是对象或数组的字段)。It then indexes this primitive value, along with the full path to that field.然后,它对该原语值以及该字段的完整路径进行索引。
For example, consider the following document:例如,考虑以下文档:
{ "parentField" : { "nestedField" : "nestedValue", "nestedObject" : { "deeplyNestedField" : "deeplyNestedValue" }, "nestedArray" : [ "nestedArrayElementOne", [ "nestedArrayElementTwo" ] ] } }
A wildcard index which includes 包含parentField
records the following entries:parentField
的通配符索引记录以下条目:
"parentField.nestedField" : "nestedValue"
"parentField.nestedObject.deeplyNestedField" : "deeplyNestedValue"
"parentField.nestedArray" : "nestedArrayElementOne"
"parentField.nestedArray" : ["nestedArrayElementTwo"]
Note that the records for 请注意,parentField.nestedArray
do not include the array position for each element. parentField.nestedArray
的记录不包括每个元素的数组位置。Wildcard indexes ignore array element positions when recording the element into the index. 在将元素记录到索引中时,通配符索引忽略数组元素位置。Wildcard indexes can still support queries that include explicit array indices. 通配符索引仍然可以支持包含显式数组索引的查询。See Queries with Explicit Array Indices for more information.有关详细信息,请参阅带有显式数组索引的查询。
For more information on wildcard index behavior with nested objects, see Nested Objects.有关嵌套对象的通配符索引行为的详细信息,请参阅嵌套对象。
For more information on wildcard index behavior with nested arrays, see Nested Arrays.有关嵌套数组的通配符索引行为的详细信息,请参阅嵌套数组。
When a wildcard index encounters a nested object, it descends into the object and indexes its contents. 当通配符索引遇到嵌套对象时,它会下降到该对象中并为其内容编制索引。For example:例如:
{ "parentField" : { "nestedField" : "nestedValue", "nestedArray" : ["nestedElement"] "nestedObject" : { "deeplyNestedField" : "deeplyNestedValue" } } }
A wildcard index which includes 包含parentField
descends into the object to traverse and index its contents:parentField
的通配符索引下降到对象中以遍历和索引其内容:
The wildcard index continues traversing any additional nested objects or arrays until it reaches a primitive value (i.e. a field that is not an object or array). 通配符索引继续遍历任何其他嵌套对象或数组,直到它达到原始值(即,不是对象或数组的字段)。It then indexes this primitive value, along with the full path to that field.然后,它对该原语值以及该字段的完整路径进行索引。
Given the sample document, the wildcard index adds the following records to the index:给定示例文档,通配符索引将以下记录添加到索引中:
"parentField.nestedField" : "nestedValue"
"parentField.nestedObject.deeplyNestedField" : "deeplyNestedValue"
"parentField.nestedArray" : "nestedElement"
For more information on wildcard index behavior with nested arrays, see Nested Arrays.有关嵌套数组的通配符索引行为的详细信息,请参阅嵌套数组。
When a wildcard index encounters a nested array, it attempts to traverse the array to index its elements. 当通配符索引遇到嵌套数组时,它会尝试遍历数组以索引其元素。If the array is itself an element in a parent array (i.e. an embedded array), the wildcard index instead records the entire array as a value instead of traversing its contents. 如果数组本身是父数组(即嵌入数组)中的元素,则通配符索引将整个数组记录为值,而不是遍历其内容。For example:例如:
{ "parentArray" : [ "arrayElementOne", [ "embeddedArrayElement" ], "nestedObject" : { "nestedArray" : [ "nestedArrayElementOne", "nestedArrayElementTwo" ] } ] }
A wildcard index which includes 包含parentArray
descends into the array to traverse and index its contents:parentArray
的通配符索引下降到数组中以遍历和索引其内容:
The wildcard index continues traversing any additional nested objects or arrays until it reaches a primitive value (i.e. a field that is not an object or array). 通配符索引继续遍历任何其他嵌套对象或数组,直到它达到原始值(即,不是对象或数组的字段)。It then indexes this primitive value, along with the full path to that field.然后,它对该原语值以及该字段的完整路径进行索引。
Given the sample document, the wildcard index adds the following records to the index:给定示例文档,通配符索引将以下记录添加到索引中:
"parentArray" : "arrayElementOne"
"parentArray" : ["embeddedArrayElement"]
"parentArray.nestedObject.nestedArray" : "nestedArrayElementOne"
"parentArray.nestedObject.nestedArray" : "nestedArrayElementTwo"
Note that the records for 请注意,parentField.nestedArray
do not include the array position for each element. parentField.nestedArray
的记录不包括每个元素的数组位置。Wildcard indexes ignore array element positions when recording the element into the index. 在将元素记录到索引中时,通配符索引忽略数组元素位置。Wildcard indexes can still support queries that include explicit array indices. 通配符索引仍然可以支持包含显式数组索引的查询。See Queries with Explicit Array Indices for more information.有关详细信息,请参阅带有显式数组索引的查询。
You cannot specify the following properties for a wildcard index:不能为通配符索引指定以下属性:
You cannot create the following index types using wildcard syntax:不能使用通配符语法创建以下索引类型:
Wildcard Indexes are distinct from and incompatible with Wildcard Text Indexes. 通配符索引与通配符文本索引不同,并且不兼容。Wildcard indexes cannot support queries using the 通配符索引不能支持使用$text
operator.$text
运算符的查询。
For complete documentation on wildcard index creation restrictions, see Incompatible Index Types or Properties.有关通配符索引创建限制的完整文档,请参阅不兼容索引类型或属性。
Wildcard indexes can support a covered queryonly if all of the following are true:如果满足以下所有条件,则通配符索引可以支持覆盖查询:
_id
and includes only the query field._id
并仅包括查询字段。Consider the following wildcard index on the 考虑employees
collection:employees
集合上的以下通配符索引:
db.employees.createIndex( { "$**" : 1 } )
The following operation queries for a single field 以下操作查询单个字段lastName
and projects out all other fields from the resulting document:lastName
,并从结果文档中投影出所有其他字段:
db.employees.find( { "lastName" : "Doe" }, { "_id" : 0, "lastName" : 1 } )
Assuming that the specified 假设指定的lastName
is never an array, MongoDB can use the $**
wildcard index for supporting a covered query.lastName
永远不是数组,MongoDB可以使用$**
通配符索引来支持覆盖查询。
Wildcard indexes can support at most one query predicate field. 通配符索引最多可以支持一个查询谓词字段。That is:即:
However, MongoDB may use the same wildcard index for satisfying each independent argument of the query 但是,MongoDB可以使用相同的通配符索引来满足查询$or
or aggregation $or
operators.$or
或聚合$or
运算符的每个独立参数。
MongoDB can use a wildcard index for satisfying the MongoDB可以使用通配符索引来满足sort()
only if all of the following are true:sort()
,前提是以下所有条件均为真:
sort()
specifies only the query predicate field.sort()
仅指定查询谓词字段。If the above conditions are not met, MongoDB cannot use the wildcard index for the sort. 如果不满足上述条件,MongoDB将无法使用通配符索引进行排序。MongoDB does not support MongoDB不支持需要不同于查询谓词索引的sort()
operations that require a different index from that of the query predicate. sort()
操作。For more information, see Index Intersection and Sort.有关详细信息,请参阅索引交集和排序。
Consider the following wildcard index on the 考虑products
collection:products
集合上的以下通配符索引:
db.products.createIndex( { "product_attributes.$**" : 1 } )
The following operation queries for a single field 以下操作查询单个字段product_attributes.price
and sorts on that same field:product_attribute.price
,并对该字段进行排序:
db.products.find( { "product_attributes.price" : { $gt : 10.00 } }, ).sort( { "product_attributes.price" : 1 } )
Assuming that the specified 假设指定的价格永远不是数组,MongoDB可以使用price
is never an array, MongoDB can use the product_attributes.$**
wildcard index for satisfying both the find()
and sort()
.product_attributes.$**
满足find()
和sort()
的通配符索引。
null
的查询条件。For details, see Unsupported Query and Aggregation Patterns.有关详细信息,请参阅不支持的查询和聚合模式。
MongoDB wildcard indexes do not record the array position of any given element in an array during indexing. MongoDB通配符索引在索引期间不记录数组中任何给定元素的数组位置。However, MongoDB may still select the wildcard index to answer a query which includes a field path with one or more explicit array indices (for example, 但是,MongoDB仍然可以选择通配符索引来回答包含具有一个或多个显式数组索引的字段路径的查询(例如,parentArray.0.nestedArray.0
). parentArray.0.nestedArray.0
)。Due to the increasing complexity of defining index bounds for each consecutive nested array, MongoDB does not consider the wildcard index to answer a given field path in the query if that path contains more than 由于为每个连续嵌套数组定义索引边界越来越复杂,如果路径包含8
explicit array indices. 8
个以上的显式数组索引,MongoDB不会考虑使用通配符索引来回答查询中的给定字段路径。MongoDB can still consider the wildcard index to answer other field paths in the query.MongoDB仍然可以考虑使用通配符索引来回答查询中的其他字段路径。
For Example:例如
{ "parentObject" : { "nestedArray" : [ "elementOne", { "deeplyNestedArray" : [ "elementTwo" ] } ] } }
MongoDB can select a wildcard index which includes MongoDB可以选择包含parentObject
to satisfy the following queries:parentObject
的通配符索引,以满足以下查询:
"parentObject.nestedArray.0" : "elementOne"
"parentObject.nestedArray.1.deeplyNestedArray.0" : "elementTwo"
If a given field path in the query predicate specifies more than 8 explicit array indices, MongoDB does not consider the wildcard index for answering that field path. 如果查询谓词中的给定字段路径指定了8个以上的显式数组索引,MongoDB将不考虑用于回答该字段路径的通配符索引。MongoDB instead either selects another eligible index to answer the query, or performs a collection scan.相反,MongoDB要么选择另一个符合条件的索引来回答查询,要么执行集合扫描。
Note that wildcard indexes themselves do not have any limits on the depth to which they traverse a document while indexing it; the limitation only applies to queries which explicitly specify exact array indices. 请注意,通配符索引本身对索引文档时遍历文档的深度没有任何限制;该限制仅适用于显式指定精确数组索引的查询。By issuing the same queries without the explicit array indices, MongoDB may select the wildcard index to answer the query:通过发出没有显式数组索引的相同查询,MongoDB可以选择通配符索引来回答查询:
"parentObject.nestedArray" : "elementOne"
"parentObject.nestedArray.deeplyNestedArray" : "elementTwo"