Sparse indexes only contain entries for documents that have the indexed field, even if the index field contains a null value. The index skips over any document that is missing the indexed field. The index is "sparse" because it does not include all documents of a collection. By contrast, non-sparse indexes contain all documents in a collection, storing null values for those documents that do not contain the indexed field.稀疏索引仅包含具有索引字段的文档的条目,即使索引字段包含null值。索引跳过任何缺少索引字段的文档。索引是“稀疏的”,因为它不包括集合的所有文档。相比之下,非稀疏索引包含集合中的所有文档,为不包含索引字段的文档存储null值。
Important
Partial indexes can function as sparse indexes, but also support filter expressions for conditions beyond whether a field exists. Use a partial index for greater control if you need precise filtering.部分索引可以作为稀疏索引,但也支持字段是否存在以外的条件的筛选表达式。如果需要精确筛选,请使用部分索引进行更好的控制。
Create a Sparse Index创建稀疏索引
To create a sparse index, use the 要创建稀疏索引,请使用db.collection.createIndex() method with the sparse option set to true.db.collection.createIndex()方法,并将sparse选项设置为true。
For example, the following operation in 例如,mongosh creates a sparse index on the xmpp_id field of the addresses collection:mongosh中的以下操作在地址集合的xmpp_id字段上创建稀疏索引:
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
The index does not index documents that do not include the 该索引不会对不包含xmpp_id field.xmpp_id字段的文档进行索引。
Note
Do not confuse sparse indexes in MongoDB with block-level indexes in other databases. Think of them as dense indexes with a specific filter.不要将MongoDB中的稀疏索引与其他数据库中的块级索引混淆。将它们视为具有特定筛选器的密集索引。
Behavior行为
Sparse Index and Incomplete Results稀疏指数和不完整结果
If a sparse index would result in an incomplete result set for queries and sort operations, MongoDB will not use that index unless a 如果稀疏索引会导致查询和排序操作的结果集不完整,MongoDB将不会使用该索引,除非hint() explicitly specifies the index.hint()显式指定该索引。
For example, the query 例如,除非明确提示,否则查询{ x: { $exists: false } } will not use a sparse index on the x field unless explicitly hinted. See Sparse Index On A Collection Cannot Return Complete Results for an example that details the behavior.{ x: { $exists: false } }不会在x字段上使用稀疏索引。有关详细行为的示例,请参阅集合上的稀疏索引无法返回完整结果。
If you include a 如果在对集合中的所有文档执行hint() that specifies a sparse index when you perform a count() of all documents in a collection (i.e. with an empty query predicate), the sparse index is used even if the sparse index results in an incorrect count.count()时包含一个指定稀疏索引的hint()(即使用空查询谓词),即使稀疏索引导致计数不正确,也会使用稀疏索引。
db.collection.insertOne( { _id: 1, y: 1 } );
db.collection.createIndex( { x: 1 }, { sparse: true } );
db.collection.find().hint( { x: 1 } ).count();
To obtain the correct count, do not 为了获得正确的计数,在对集合中的所有文档进行计数时,不要使用稀疏索引来hint() with a sparse index when performing a count of all documents in a collection.hint()。
db.collection.find().count();
db.collection.createIndex( { y: 1 } );
db.collection.find().hint( { y: 1 } ).count();Indexes that are Sparse by Default默认情况下为稀疏的索引
The following index types are always sparse:以下索引类型总是稀疏的:
Sparse Compound Indexes稀疏复合指数
Compound indexes can contain different types of sparse indexes. The combination of index types determines how the compound index matches documents.复合索引可以包含不同类型的稀疏索引。索引类型的组合决定了复合索引如何匹配文档。
This table summarizes the behavior of a compound index that contains different types of sparse indexes:此表总结了包含不同类型稀疏索引的复合索引的行为:
geospatial fields. Does not index documents in the ascending or descending indexes.geospatial字段的值时,才对文档进行索引。不按升序或降序索引对文档进行索引。 | |
text fields. Does not index documents in the ascending or descending indexes.text字段匹配时,才对其进行索引。不按升序或降序索引对文档进行索引。 |
Sparse and Unique Properties稀疏和独特的属性
An index that is both sparse and unique prevents a collection from having documents with duplicate values for a field but allows multiple documents that omit the key.稀疏且唯一的索引可以防止集合中的文档具有字段的重复值,但允许多个文档省略键。
Examples示例
Create a Sparse Index On A Collection在集合上创建稀疏索引
Consider a collection 考虑一个包含以下文档的集合scores that contains the following documents:scores:
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
The collection has a sparse index on the field 该集合在字段score:score上有一个稀疏索引:
db.scores.createIndex( { score: 1 } , { sparse: true } )
Then, the following query on the 然后,对scores collection uses the sparse index to return the documents that have the score field less than ($lt) 90:scores集合的以下查询使用稀疏索引返回score字段小于($lt)90的文档:
db.scores.find( { score: { $lt: 90 } } )
Because the document for the userid 因为用户ID"newbie" does not contain the score field and thus does not meet the query criteria, the query can use the sparse index to return the results:"newbie"的文档不包含score字段,因此不符合查询条件,所以查询可以使用稀疏索引返回结果:
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }Sparse Index On A Collection Cannot Return Complete Results集合上的稀疏索引无法返回完整结果
Consider a collection 考虑一个包含以下文档的集合scores that contains the following documents:scores:
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
The collection has a sparse index on the field 该集合在字段score:score上有一个稀疏索引:
db.scores.createIndex( { score: 1 } , { sparse: true } )
Because the document for the userid 因为用户ID"newbie" does not contain the score field, the sparse index does not contain an entry for that document."newbie"的文档不包含score字段,所以稀疏索引不包含该文档的条目。
Consider the following query to return all documents in the 考虑以下查询以返回scores collection, sorted by the score field:scores集合中的所有文档,按scores字段排序:
db.scores.find().sort( { score: -1 } )
Even though the sort is by the indexed field, MongoDB will not select the sparse index to fulfill the query in order to return complete results:即使排序是按索引字段进行的,MongoDB也不会选择稀疏索引来完成查询,以返回完整的结果:
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
To use the sparse index, explicitly specify the index with 要使用稀疏索引,请使用hint():hint()显式指定索引:
db.scores.find().sort( { score: -1 } ).hint( { score: 1 } )
The use of the index results in the return of only those documents with the 使用索引只返回具有score field:score字段的文档:
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
Sparse Index with Unique Constraint具有唯一约束的稀疏索引
Consider a collection 考虑一个包含以下文档的集合scores that contains the following documents:scores:
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
You could create an index with a unique constraint and sparse filter on the 您可以使用以下操作在score field using the following operation:score字段上创建具有唯一约束和稀疏筛选器的索引:
db.scores.createIndex( { score: 1 } , { sparse: true, unique: true } )
This index would permit the insertion of documents that had unique values for the 该索引将允许插入score field or did not include a score field. As such, given the existing documents in the scores collection, the index permits the following insert operations:score字段具有唯一值或不包含score字段的文档。因此,考虑到分数集合中的现有文档,该索引允许以下插入操作:
db.scores.insertMany( [
{ "userid": "newbie", "score": 43 },
{ "userid": "abby", "score": 34 },
{ "userid": "nina" }
] )
However, the index would not permit the addition of the following documents since documents already exists with 然而,该指数不允许添加以下文件,因为已经存在score value of 82 and 90:score为82和90的文件:
db.scores.insertMany( [
{ "userid": "newbie", "score": 82 },
{ "userid": "abby", "score": 90 }
] )Sparse and Non-Sparse Unique Indexes稀疏和非稀疏唯一索引
Starting in MongoDB 5.0, unique sparse and unique non-sparse indexes with the same key pattern can exist on a single collection.从MongoDB 5.0开始,具有相同键模式的唯一稀疏和唯一非稀疏索引可以存在于单个集合上。
Unique and Sparse Index Creation独特而稀疏的索引创建
This example creates multiple indexes with the same key pattern and different 此示例使用相同的键模式和不同的sparse options:sparse选项创建多个索引:
db.scoreHistory.createIndex( { score : 1 }, { name: "unique_index", unique: true } )
db.scoreHistory.createIndex( { score : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )Basic and Sparse Index Creation基本和稀疏索引创建
You can also create basic indexes with the same key pattern with and without the sparse option:您还可以在有和没有稀疏选项的情况下,使用相同的键模式创建基本索引:
db.scoreHistory.createIndex( { score : 1 }, { name: "sparse_index", sparse: true } )
db.scoreHistory.createIndex( { score : 1 }, { name: "basic_index" } )