Sparse Indexes稀疏索引

On this page本页内容

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.相反,非稀疏索引包含集合中的所有文档,为不包含索引字段的文档存储空值。

Important重要

Changed in version 3.2.在版本3.2中更改

Starting in MongoDB 3.2, MongoDB provides the option to create partial indexes. 从MongoDB 3.2开始,MongoDB提供了创建部分索引的选项。Partial indexes offer a superset of the functionality of sparse indexes. 部分索引提供了稀疏索引功能的超集。If you are using MongoDB 3.2 or later, partial indexes should be preferred over sparse indexes.如果您使用的是MongoDB 3.2或更高版本,则应首选部分索引而不是稀疏索引。

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选项设置为trueFor example, the following operation in mongosh creates a sparse index on the xmpp_id field of the addresses collection:例如,mongosh中的以下操作在addresses集合的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. 不要将MongoDB中的稀疏索引与其他数据库中的块级索引混淆。Think of them as dense indexes with a specific filter.可以将它们视为具有特定筛选器的密集索引。

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 hint() explicitly specifies the index.如果稀疏索引会导致查询和排序操作的结果集不完整,MongoDB将不会使用该索引,除非hint()显式指定索引。

For example, the query { x: { $exists: false } } will not use a sparse index on the x field unless explicitly hinted. 例如,除非明确提示,否则查询{ x: { $exists: false } }不会在x字段上使用稀疏索引。See Sparse Index On A Collection Cannot Return Complete Results for an example that details the behavior.有关详细行为的示例,请参阅集合上的稀疏索引无法返回完整结果

Changed in version 3.4.在版本3.4中更改

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默认情况下稀疏的索引

2dsphere (version 2), 2d, geoHaystack, and text indexes are always sparse.2dsphere (第2版)索引2d索引geoHaystack索引text索引始终是稀疏的。

sparse Compound Indexes复合指数

Sparse compound indexes that only contain ascending/descending index keys will index a document as long as the document contains at least one of the keys.仅包含升序/降序索引键的稀疏复合索引将索引文档,只要该文档包含至少一个键。

For sparse compound indexes that contain a geospatial key (i.e. 2dsphere, 2d, or geoHaystack index keys) along with ascending/descending index key(s), only the existence of the geospatial field(s) in a document determine whether the index references the document.对于包含地理空间键(即2dsphere2dgeoHaystack索引键)以及升序/降序索引键的稀疏复合索引,只有文档中地理空间字段的存在才能确定索引是否引用文档。

For sparse compound indexes that contain text index keys along with ascending/descending index keys, only the existence of the text index field(s) determine whether the index references a document.对于包含>text索引键以及升序/降序索引键的稀疏复合索引,只有text索引字段的存在才能确定索引是否引用文档。

sparse and 属性和unique Properties属性

An index that is both sparse and unique prevents 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集合的查询使用稀疏索引返回分数字段小于($lt90的文档:

db.scores.find( { score: { $lt: 90 } } )

Because the document for the userid "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 "newbie" does not contain the score field, the sparse index does not contain an entry for that document.因为用户ID"newbie"的文档不包含score字段,所以稀疏索引不包含该文档的条目。

Consider the following query to return all documents in the scores collection, sorted by the score field:考虑以下查询以返回scores集合中按score字段排序的所有文档:

db.scores.find().sort( { score: -1 } )

Even though the sort is by the indexed field, MongoDB will notselect 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. 该索引允许插入具有score字段唯一值不包括score字段的文档。As such, given the existing documents in the scores collection, the index permits the following insert operations:因此,考虑到scores集合中的现有文档,索引允许以下插入操作

db.scores.insertMany( [
   { "userid": "AAAAAAA", "score": 43 },
   { "userid": "BBBBBBB", "score": 34 },
   { "userid": "CCCCCCC" },
   { "userid": "DDDDDDD" }
] )

However, the index would not permit the addition of the following documents since documents already exists with score value of 82 and 90:但是,索引不允许添加以下文档,因为已经存在score值为8290的文档:

db.scores.insertMany( [
   { "userid": "AAAAAAA", "score": 82 },
   { "userid": "BBBBBBB", "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" } )
←  Hidden IndexesIndex Builds on Populated Collections →