- MongoDB官方文档中文版
- MongoDB中文手册说明
- MongoDB简介
- 安装 MongoDB
- The mongo Shell
- MongoDB CRUD 操作
- 聚合
- 数据模型
- 事务
- 索引
- 安全
- 安全检查列表
- 启用访问控制
- 身份验证
- 基于角色的访问控制
- TLS / SSL(传输加密)
- 静态加密
- 客户端字段级加密
- 审计
- 网络和配置强化
- 实现字段级别修订
- 安全参考
- 附录
- 变更流
- 复制
- 分片
- 分片键
- 哈希分片
- 范围分片
- 区
- 管理分片区
- 按位置细分数据
- 用于更改SLA或SLO的分层硬件
- 按应用或客户细分数据
- 仅插入工作负载的分布式本地写入
- 管理分片区
- 使用块进行数据分区
- 在分片集群中拆分数据块
- 管理
- 存储
- 存储引擎
- 日志记录
- 管理日志记录
- GridFS
- FAQ:MongoDB 存储
- 存储引擎
- 参考
- 运算符
- 查询与映射运算符
- 更新运算符
- 聚合管道阶段
- 聚合管道操作符
- $abs (aggregation)
- $acos (aggregation)
- $acosh (aggregation)
- $add (aggregation)
- $addToSet (aggregation)
- $allElementsTrue (aggregation)
- $and (aggregation)
- $anyElementTrue (aggregation)
- $arrayElemAt (aggregation)
- $arrayToObject (aggregation)
- $asin (aggregation)
- $asinh (aggregation)
- $atan (aggregation)
- $atan2 (aggregation)
- $atanh (aggregation)
- $avg (aggregation)
- $ceil (aggregation)
- $cmp (aggregation)
- $concat (aggregation)
- $concatArrays (aggregation)
- $cond (aggregation)
- $convert (aggregation)
- $cos (aggregation)
- $dateFromParts (aggregation)
- $dateToParts (aggregation)
- $dateFromString (aggregation)
- $literal (aggregation)
- 查询修饰符
- 数据库命令
- 聚合命令
- 地理空间命令
- 查询和写操作命令
- 查询计划缓存命令
- 认证命令
- 用户管理命令
- 角色管理命令
- 复制命令
- 分片命令
- 会话命令
- 管理命令
- 诊断命令
- 免费监控命令
- 系统事件审计命令
- mongo Shell 方法
- 集合方法
- db.collection.aggregate()
- db.collection.bulkWrite()
- db.collection.copyTo()
- db.collection.count()
- db.collection.countDocuments()
- db.collection.estimatedDocumentCount()
- db.collection.createIndex()
- db.collection.createIndexes()
- db.collection.dataSize()
- db.collection.deleteOne()
- db.collection.deleteMany()
- db.collection.distinct()
- db.collection.drop()
- db.collection.dropIndex()
- db.collection.dropIndexes()
- db.collection.ensureIndex()
- db.collection.explain()
- db.collection.find()
- db.collection.findAndModify()
- db.collection.findOne()
- db.collection.findOneAndDelete()
- db.collection.findOneAndReplace()
- db.collection.findOneAndUpdate()
- db.collection.getIndexes()
- db.collection.getShardDistribution()
- db.collection.getShardVersion()
- db.collection.insert()
- db.collection.insertOne()
- db.collection.insertMany()
- db.collection.isCapped()
- db.collection.latencyStats()
- db.collection.mapReduce()
- db.collection.reIndex()
- db.collection.remove()
- db.collection.renameCollection()
- db.collection.replaceOne()
- db.collection.save()
- db.collection.stats()
- db.collection.storageSize()
- db.collection.totalIndexSize()
- db.collection.totalSize()
- db.collection.update()
- db.collection.updateOne()
- db.collection.updateMany()
- db.collection.watch()
- db.collection.validate()
- 词汇表
- 默认的MongoDB端口
- 默认的MongoDB读/写关注
- 服务器会话
- MongoDB驱动
- FAQ
- 联系我们
- 更多资料
- [快学Mongo]
- [Mongo问题讨论区]
- [Mongo 驱动使用手册]
- 本书使用 GitBook 发布
部分索引
部分索引
在本页面
新版本3.2.
部分索引只索引集合中满足指定筛选器表达式的文档。通过索引集合中文档的子集,部分索引可以降低存储需求,并降低创建和维护索引的性能成本。
创建部分索引
使用db.collection.createIndex()方法和'partialFilterExpression'选项。“partialFilterExpression”选项接受指定筛选条件的文档,使用:
例如,下面的操作创建一个复合索引,该索引只对“rating”字段大于5的文档进行索引。
db.restaurants.createIndex(
{ cuisine: 1, name: 1 },
{ partialFilterExpression: { rating: { $gt: 5 } } }
)
你可以为所有的MongoDB索引类型,指定一个partialFilterExpression选项.
行为
查询范围
如果使用索引导致结果集不完整,则MongoDB不会将部分索引用于查询或排序操作。
若要使用部分索引,查询必须将筛选器表达式(或指定筛选器表达式子集的经过修改的筛选器表达式)作为其查询条件的一部分。
例如,给定以下索引:
db.restaurants.createIndex(
{ cuisine: 1 },
{ partialFilterExpression: { rating: { $gt: 5 } } }
)
下面的查询可以使用索引,因为查询谓词包含条件“rating: {$gte: 8}”
,它匹配索引筛选器表达式“rating: {$gt: 5}”
匹配的文档子集:
db.restaurants.find( { cuisine: "Italian", rating: { $gte: 8 } } )
但是,以下查询不能在“cuisine”字段上使用部分索引,因为使用该索引会导致不完整的结果集。具体来说,查询谓词包括条件rating: {$lt: 8}
,而索引有过滤器rating: {$gt: 5}
。也就是说,查询{cuisine: "Italian", rating: {$lt: 8}}
匹配的文档(例如,一家评级为1的意大利餐厅)比编入索引的文档更多。
db.restaurants.find( { cuisine: "Italian", rating: { $lt: 8 } } )
类似地,以下查询不能使用部分索引,因为查询谓词不包括筛选器表达式,并且使用索引将返回不完整的结果集。
db.restaurants.find( { cuisine: "Italian" } )
与“sparse”索引进行比较
提示
部分索引代表sparse索引提供的功能的超集,应优先于sparse索引。
部分索引提供了一种比sparse索引索引更有表现力的机制来指定索引哪些文档。
Sparse索引根据索引字段的存在性选择文档进行索引,对于复合索引则根据索引字段的存在性选择文档。
部分索引根据指定的筛选器确定索引项。过滤器可以包括索引键以外的字段,并可以指定条件,而不仅仅是存在检查。例如,部分索引可以实现与sparse索引相同的行为:
db.contacts.createIndex(
{ name: 1 },
{ partialFilterExpression: { name: { $exists: true } } }
)
此部分索引支持与“name”字段上的sparse索引相同的查询。
但是,部分索引还可以在索引键以外的字段上指定筛选器表达式。例如,下面的操作创建了一个部分索引,其中索引在name字段上,但是过滤器表达式在email字段上:
db.contacts.createIndex(
{ name: 1 },
{ partialFilterExpression: { email: { $exists: true } } }
)
为了让查询优化器选择此部分索引,查询谓词必须包含“name”字段上的条件,以及“email”字段上的非空匹配。
例如,下面的查询可以使用索引,因为它包括' name '字段上的条件和' email '字段上的非空匹配:
db.contacts.find( { name: "xyz", email: { $regex: /\.org$/ } } )
但是,以下查询不能使用索引,因为它在“email”字段上包含了一个null匹配,这是过滤器表达式{email: {$exists: true}}
不允许的:
db.contacts.find( { name: "xyz", email: { $exists: false } } )
限制
在MongoDB中,您不能创建仅在选项上有所不同的多个索引版本。因此,您不能创建仅因过滤器表达式而不同的多个部分索引。
您不能同时指定partialFilterExpression
选项和sparse
选项。
MongoDB 3.0或更早版本不支持部分索引。要使用部分索引,必须使用MongoDB 3.2或更高版本。对于分片集群或复制集,所有节点必须是版本3.2或更高。
_id
索引不能是部分索引。
分片键索引不能是部分索引。
例子
在集合上创建部分索引
考虑包含类似于以下文档的集合restaurants
{
"_id" : ObjectId("5641f6a7522545bc535b5dc9"),
"address" : {
"building" : "1007",
"coord" : [
-73.856077,
40.848447
],
"street" : "Morris Park Ave",
"zipcode" : "10462"
},
"borough" : "Bronx",
"cuisine" : "Bakery",
"rating" : { "date" : ISODate("2014-03-03T00:00:00Z"),
"grade" : "A",
"score" : 2
},
"name" : "Morris Park Bake Shop",
"restaurant_id" : "30075445"
}
您可以在borough
和cuisine
字段上添加部分索引,仅选择索引rating.grade
字段为的文档A
:
db.restaurants.createIndex(
{ borough: 1, cuisine: 1 },
{ partialFilterExpression: { 'rating.grade': { $eq: "A" } } }
)
然后,对restaurants
集合的以下查询使用部分索引返回Bronx中rating.grade
等于的餐厅A
:
db.restaurants.find( { borough: "Bronx", 'rating.grade': "A" } )
但是,以下查询不能使用部分索引,因为查询表达式不包含该rating.grade
字段:
db.restaurants.find( { borough: "Bronx", cuisine: "Bakery" } )
具有唯一约束的部分索引
部分索引仅索引集合中符合指定过滤器表达式的文档。如果同时指定 partialFilterExpression
和约束,则唯一约束仅适用于满足过滤器表达式的文档。如果文档不符合过滤条件,则具有唯一约束的部分索引不会阻止插入不符合唯一约束的文档。
例如,集合users包含以下文档:
{ "_id" : ObjectId("56424f1efa0358a27fa1f99a"), "username" : "david", "age" : 29 }
{ "_id" : ObjectId("56424f37fa0358a27fa1f99b"), "username" : "amanda", "age" : 35 }
{ "_id" : ObjectId("56424fe2fa0358a27fa1f99c"), "username" : "rajiv", "age" : 57 }
下面的操作创建了一个索引,该索引在“username”字段上指定了一个unique constraint和一个部分过滤表达式age: {$gte: 21}
。
db.users.createIndex(
{ username: 1 },
{ unique: true, partialFilterExpression: { age: { $gte: 21 } } }
)
由于指定用户名的文档已经存在,且“age”字段大于21,因此索引防止插入以下文档:
db.users.insert( { username: "david", age: 27 } )
db.users.insert( { username: "amanda", age: 25 } )
db.users.insert( { username: "rajiv", age: 32 } )
但是,允许使用重复用户名的以下文档,因为唯一约束只适用于“age”大于或等于21的文档。
db.users.insert( { username: "david", age: 20 } )
db.users.insert( { username: "amanda" } )
db.users.insert( { username: "rajiv", age: null } )
Copyright © 上海锦木信息技术有限公司 all right reserved,由 MongoDB汉化小组 提供技术支持文件修订时间: 2020-10-11 20:53:05