MongoDB-CN-Manual
  • MongoDB中文手册|官方文档中文版
  • MongoDB用户手册说明
  • MongoDB简介
    • 入门
    • 数据库和集合
      • 视图
      • 按需物化视图
      • 封顶集合
      • 时间序列集合
    • 文档
    • BSON类型
      • Comparison and Sort Order
      • MongoDB Extended JSON (v2)
      • MongoDB Extended JSON (v1)
  • 安装 MongoDB
    • 安装MongoDB社区版
      • 在Linux上安装MongoDB社区版
      • 在macOS上安装MongoDB社区版
      • 在Windows上安装MongoDB社区版
    • 安装MongoDB企业版
      • 在Linux上安装MongoDB企业版
      • 在Mac OS安装MongoDB企业版
      • 在Windows安装MongoDB企业版
      • 使用Docker安装MongoDB企业版
    • 将社区版MongoDB升级到企业版MongoDB
    • 验证MongoDB软件包的完整性
  • The mongo Shell
    • 配置mongo Shell
    • 使用 mongo Shell帮助
    • 为mongo Shell编写脚本
    • mongo Shell中的数据类型
    • mongo Shell 快速参考
  • MongoDB CRUD操作
    • 插入文档
      • 插入方法
    • 查询文档
      • 在mongo Shell中迭代游标
      • 从查询返回的项目字段
      • 查询嵌入式文档数组
      • 查询数组
      • 查询空字段或缺少字段
      • 查询嵌入/嵌套文档
    • 更新文档
      • 更新方法
      • 聚合管道更新
    • 删除文档
      • 删除方法
    • 地理空间查询
      • 用地理空间查询查找餐馆
      • GeoJSON对象
    • 批量写入操作
    • 可重试写入
    • 可重试读取
    • SQL到MongoDB的映射图表
    • 文本搜索
      • 文本索引
      • 文本索引操作
      • 集合管道中的文本索引
      • 文本索引语言
    • Read Concern读关注
      • 读关注 "local"
      • 读关注 "available"
      • 读关注 "majority"
      • 读关注 "linearizable"
      • 读关注 "snapshot"
    • Write Concern写关注
    • MongoDB CRUD概念
      • 原子性和事务
      • 读隔离性,一致性和近因性
        • 因果一致性和读写关注
      • 分布式查询
      • 通过findAndModify进行线性化读取
      • 查询计划
      • 查询优化
        • 评估当前操作性能
        • 优化查询性能
        • 写操作性能
        • 说明结果
      • 分析查询表现
      • Tailable 游标
  • MongoDB聚合
    • 聚合管道
      • 聚合管道优化
      • 聚合管道限制
      • 聚合管道和分片集合
      • 使用 Zip Code 数据集进行聚合
      • 使用用户首选项数据进行聚合
    • Map-Reduce
      • Map-Reduce 和分片集合
      • Map-Reduce 并发
      • Map-Reduce 示例
      • 执行增量 Map-Reduce
      • 对 Map Function 进行故障排除
      • 排除 Reduce Function 问题
      • Map-Reduce转换到聚合管道
    • 聚合参考
      • 聚合管道快速参考
      • 聚合命令
      • 聚合命令对比
      • 聚合表达式中的变量
      • SQL 到聚合映射图表
  • MongoDB数据模型
    • 数据建模介绍
    • 模式验证
    • 数据模型设计
      • 一对一嵌套关系模型
  • MongoDB事务
  • MongoDB事务
    • 驱动程序 API
    • 生产注意事项
    • 生产注意事项 (分片集群)
    • 事务操作
  • MongoDB索引
    • 单字段索引
    • 复合索引
    • 多键索引
      • 多键索引范围
    • 文本索引
      • 为文本索引指定语言
      • 指定文本索引的名称
      • 用权重控制搜索结果
      • 限制扫描条目的数量
    • 通配符索引
      • 通配符索引限制
    • 2dsphere 索引
      • 查询一个2dsphere索引
    • 2d 索引
      • 创建一个2d索引
      • 查询一个2d索引
      • 2d索引内部
      • 使用球面几何计算距离
    • geoHaystack 索引
      • 创建Haystack索引
      • 查询Haystack索引
    • 哈希索引
    • 索引特性
      • TTL 索引
        • 通过设置TTL使集合中的数据过期
      • 唯一索引
      • 部分索引
      • 不分大小写索引
      • Sparse 索引
    • 在填充的集合上建立索引
      • 在副本集上建立滚动索引
      • 在分片群集上建立滚动索引
    • 索引交集
    • 管理索引
    • 衡量索引使用
    • 索引策略
      • 创建索引来支持查询
      • 使用索引对查询结果进行排序
      • 确保索引适合RAM
      • 创建以确保选择性的查询
    • 索引参考
  • MongoDB安全
    • 安全检查列表
    • 启用访问控制
    • 身份验证
      • 用户
        • 添加用户
        • 权限认证机制
          • SCRAM
            • 用x.509证书来认证客户端
    • 审计
      • 配置审计过滤器
      • 配置审计
      • 系统事件审计消息
    • 网络和配置强化
    • 安全参考
      • system.roles集合
      • system.users集合
      • 资源文档
      • 权限操作
    • 附录
      • 附录-A-用于测试的 OpenSSl CA 证书
      • 附录-B-用于测试的OpenSSL服务器证书
      • 附录-C-用于测试的OpenSSL客户端证书
  • Change Streams变更流
    • 变更流生产建议
    • 变更事件
  • MongoDB复制
    • 副本集成员
    • 副本集日志
    • 副本集数据同步
    • 副本集部署架构
    • 副本集成员配置教程
    • 副本集维护教程
    • MongoDB复制参考
  • MongoDB分片
    • 分片集群组件
    • 分片键
    • 哈希分片
    • 范围分片
    • 区
      • 管理分片区
      • 按位置细分数据
      • 用于更改SLA或SLO的分层硬件
      • 按应用或客户细分数据
      • 仅插入工作负载的分布式本地写入
      • 管理分片区
    • 使用块进行数据分区
      • 在分片集群中拆分数据块
    • 分片管理
      • 查看集群设置
    • 重启一个分片集群
    • [把一个分片集群迁移到不同的硬件](fen-pian/migrate-a -sharded-cluster-to-different-hardware.md)
    • 分片参考
  • MongoDB管理
    • 产品说明
    • 操作检查列表
    • 开发检查列表
    • 配置和维护
    • 性能
    • 数据中心意识
      • MongoDB部署中的工作负载隔离
      • 区
        • 管理分片区
        • 按位置细分数据
        • 用于更改SLA或SLO的分层硬件
        • 按应用或客户细分数据
        • 仅插入工作负载的分布式本地写入
        • 管理分片区
    • MongoDB备份方法
    • MongoDB监控
  • MongoDB存储
    • 存储引擎
      • WiredTiger 存储引擎
      • 内存存储引擎
    • 日志记录
      • 管理日志记录
        • GridFS
        • FAQ:MongoDB 存储
  • MongoDB参考
    • 运算符
      • 查询与映射运算符
        • 比较查询运算符
          • $eq
          • $gt
          • $gte
          • $in
          • $lt
          • $lte
          • $ne
          • $nin
        • 逻辑查询运算符
          • $and
          • $not
          • $nor
          • $or
        • 元素查询运算符
        • 评估查询运算符
        • 地理空间查询运算符
        • 数组查询运算符
        • 按位查询运算符
        • $comment
        • 映射运算符
      • 更新运算符
        • 字段更新运算符
        • 数组更新运算符
        • 按位更新运算符
      • 聚合管道阶段
      • 聚合管道操作符
        • $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端口
    • 默认的MongoDB读/写关注
    • 服务器会话
  • MongoDB FAQ
    • FAQ: MongoDB基础知识
    • FAQ: MongoDB索引
    • FAQ: MongoDB并发
    • FAQ: MongoDB分片
    • FAQ: MongoDB复制和副本集
    • FAQ: MongoDB存储
    • FAQ: MongoDB诊断
  • MongoDB 版本管理
  • 联系我们
    • Tapdata Cloud
    • MongoDB中文社区
    • 社区合作伙伴—锦木信息
由 GitBook 提供支持
在本页
  • 多键索引的交集边界
  • 多键索引的复合边界
  • 数组字段的复合索引
  • 对标量索引字段的范围查询(WiredTiger)
  • 对嵌入文档数组中的字段进行复合索引
  • 非数组字段和数组字段的复合边界
  • 数组中索引字段的复合边界
  • 查询没有$elemMatch
  • $elemMatch在不完整路径上
  1. MongoDB索引
  2. 多键索引

多键索引范围

上一页多键索引下一页文本索引

最后更新于3年前

在本页面

索引扫描的边界定义查询期间要搜索的索引部分。当索引上存在多个谓词时,MongoDB将尝试通过交集或复合的方式组合这些谓词的边界,以产生具有更小边界的扫描。

多键索引的交集边界

边界交集指的是多个边界的逻辑连接(即:AND)。例如,给定两个边界[[3,∞]]和[[-∞,6]],边界的交集得到[[3,6]]。

给定一个数组字段,请考虑一个查询,该查询在数组上指定多个谓词,并且可以使用 。如果联接连接谓词,则MongoDB可以与边界相交 。

给定数组字段,考虑一个在数组上指定多个谓词并可以使用的查询。如果一个连接谓词,MongoDB可以交叉多键索引边界。

例如,一个集合survey包含带有一个字段item和一个数组字段的文档 ratings:

{ _id: 1, item: "ABC", ratings: [ 2, 9 ] }
{ _id: 2, item: "XYZ", ratings: [ 4, 3 ] }

在ratings数组上创建一个多键索引:

db.survey.createIndex( { ratings: 1 } )

下面的查询使用要求数组至少包含一个匹配这两个条件的元素:

db.survey.find( { ratings : { $elemMatch: { $gte: 3, $lte: 6 } } } )

分别取谓词:

  • 大于或等于3的谓词(即$gte: 3)的边界为[[3,∞]];

  • 小于或等于6谓词(即$lte: 6)的边界为[[-∞,6]]。

ratings: [ [ 3, 6 ] ]
db.survey.find( { ratings : { $gte: 3, $lte: 6 } } )

查询在ratings数组中搜索至少一个大于或等于3的元素和至少一个小于或等于6的元素。因为单个元素不需要同时满足两个条件,所以MongoDB不相交边界,使用[[3,∞]]或[[-∞,6]]。MongoDB不保证它选择这两个边界中的哪一个。

多键索引的复合边界

{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }

如果MongoDB不能复合这两个边界,MongoDB总是按照前场的边界约束索引扫描,在这种情况下,a:[[3,∞]]。

数组字段的复合索引

{ _id: 1, item: "ABC", ratings: [ 2, 9 ] }
{ _id: 2, item: "XYZ", ratings: [ 4, 3 ] }
db.survey.createIndex( { item: 1, ratings: 1 } )

下面的查询在索引的两个键上指定一个条件:

db.survey.find( { item: "XYZ", ratings: { $gte: 3 } } )

分别取谓词:

  • 谓词**"XYZ"的边界是[["XYZ", "XYZ"]]**;

  • 评级:{$gte: 3}谓词的边界是[[3,∞]];

MongoDB可以复合这两个边界使用的组合边界:

{ item: [ [ "XYZ", "XYZ" ] ], ratings: [ [ 3, Infinity ] ] }

对标量索引字段的范围查询(WiredTiger)

3.4版本的改变:仅针对WiredTiger和内存存储引擎

从MongoDB 3.4开始,对于使用MongoDB 3.4或更高版本创建的多键索引,MongoDB会跟踪哪个索引字段或哪些字段导致一个索引成为多键索引。跟踪这些信息允许MongoDB查询引擎使用更紧密的索引边界

db.survey.createIndex( { item: 1, ratings: 1 } )

对于WiredTiger和内存中的存储引擎,如果一个查询操作在MongoDB 3.4或更高版本中创建的复合多键索引的索引标量字段上指定多个谓词,MongoDB将与字段的边界相交。

例如,下面的操作指定了标量字段的范围查询以及数组字段的范围查询:

db.survey.find( {
   item: { $gte: "L", $lte: "Z"}, ratings : { $elemMatch: { $gte: 3, $lte: 6 } }
} )

MongoDB将item到[[“L”,“Z”]]和评级到[[3.0,6.0]]的边界相交,使用以下的组合边界:

"item" : [ [ "L", "Z" ] ], "ratings" : [ [3.0, 6.0] ]

再举一个例子,考虑标量字段属于嵌套文档的位置。例如,一个集合survey包含以下文档:

{ _id: 1, item: { name: "ABC", manufactured: 2016 }, ratings: [ 2, 9 ] }
{ _id: 2, item: { name: "XYZ", manufactured: 2013 },  ratings: [ 4, 3 ] }

在标量字段“item.name”和“item”上创建复合多键索引。数组字段ratings:

db.survey.createIndex( { "item.name": 1, "item.manufactured": 1, ratings: 1 } )

考虑以下操作,它在标量字段上指定查询谓词:

db.survey.find( {
   "item.name": "L" ,
   "item.manufactured": 2012
} )

对于这个查询,MongoDB可以使用以下的组合边界:

"item.name" : [ ["L", "L"] ], "item.manufactured" : [ [2012.0, 2012.0] ]

早期版本的MongoDB不能合并标量字段的这些边界。

对嵌入文档数组中的字段进行复合索引

ratings: [ { score: 2, by: "mn" }, { score: 9, by: "anon" } ]

分数字段的虚线字段名是**“ratings.score”**。

非数组字段和数组字段的复合边界

考虑一个包含字段item和数组字段ratings的文档的集合survey2:

{
  _id: 1,
  item: "ABC",
  ratings: [ { score: 2, by: "mn" }, { score: 9, by: "anon" } ]
}
{
  _id: 2,
  item: "XYZ",
  ratings: [ { score: 5, by: "anon" }, { score: 7, by: "wv" } ]
}

在非数组字段item和数组ratings中的两个字段上创建复合索引。score和ratings.by:

db.survey2.createIndex( { "item": 1, "ratings.score": 1, "ratings.by": 1 } )

下面的查询为所有三个字段指定了一个条件:

db.survey2.find( { item: "XYZ",  "ratings.score": { $lte: 5 }, "ratings.by": "anon" } )

分别取谓词:

  • 谓词"XYZ"的边界是**[["XYZ", "XYZ"]]**;

  • {$lte: 5}谓词的边界是**[[-∞,5]]**;

  • by: "anon"谓词的边界是["anon", "anon"]。

MongoDB的可以复合边界为item与键或者为边界"ratings.score"或界限为"ratings.by"取决于查询谓词和索引关键字的值,。MongoDB不保证与item 领域的界限。例如,MongoDB将选择将item边界与"ratings.score"边界复合 :

{

  "item" : [ [ "XYZ", "XYZ" ] ],

  "ratings.score" : [ [ -Infinity, 5 ] ],

  "ratings.by" : [ [ MinKey, MaxKey ] ]
}

或者,MongoDB可以选择将item范围与 "ratings.by"范围进行组合:

{

  "item" : [ [ "XYZ", "XYZ" ] ],

  "ratings.score" : [ [ MinKey, MaxKey ] ],

  "ratings.by" : [ [ "anon", "anon" ] ]

}

数组中索引字段的复合边界

将同一个数组的索引键的边界复合在一起:

  • 索引键必须共享相同的字段路径,但不包括字段名称。

  • 查询必须使用该路径上的$elemMatch在字段上指定谓词。

例如,在ratings.score和ratings.by字段创建一个符合索引:

db.survey2.createIndex( { "ratings.score": 1, "ratings.by": 1 } )
db.survey2.find( { ratings: { $elemMatch: { score: { $lte: 5 }, by: "anon" } } } )

分别取谓词:

  • { $lte: 5 }谓词的边界是[-∞,5];

  • by: "anon"谓词的边界是["anon", "anon"]

MongoDB可以复合这两个边界使用的组合边界:

{ "ratings.score" : [ [ -Infinity, 5 ] ], "ratings.by" : [ [ "anon", "anon" ] ] }

查询没有$elemMatch

db.survey2.find( { "ratings.score": { $lte: 5 }, "ratings.by": "anon" } )

因为数组中嵌入的单个文档不需要同时满足这两个条件,所以MongoDB不复合边界。使用复合索引时,如果MongoDB不能约束索引的所有字段,MongoDB总是约束索引的前导字段,这里是“ratings.score”:

{
  "ratings.score": [ [ -Infinity, 5 ] ],
  "ratings.by": [ [ MinKey, MaxKey ] ]
}

$elemMatch在不完整路径上

例如,集合survey3包含一个字段item和一个数组字段ratings的文档:

{
  _id: 1,
  item: "ABC",
  ratings: [ { scores: [ { q1: 2, q2: 4 }, { q1: 3, q2: 8 } ], loc: "A" },
             { scores: [ { q1: 2, q2: 5 } ], loc: "B" } ]
}
{
  _id: 2,
  item: "XYZ",
  ratings: [ { scores: [ { q1: 7 }, { q1: 2, q2: 8 } ], loc: "B" } ]
}
db.survey3.createIndex( { "ratings.scores.q1": 1, "ratings.scores.q2": 1 } )
db.survey3.find( { ratings: { $elemMatch: { 'scores.q1': 2, 'scores.q2': 8 } } } )
db.survey3.find( { 'ratings.scores': { $elemMatch: { 'q1': 2, 'q2': 8 } } } )

译者:杨帅

因为查询使用来连接这些谓词,MongoDB可以交叉边界到:

如果查询没有将数组字段的条件与连接起来,MongoDB就不能与多键索引边界相交。考虑以下查询:

复合边界是指对的多个键使用边界。例如,给定一个复合索引{a: 1, b: 1},其中a字段的界值为[[3,∞]],b字段的界值为[[-∞,6]],复合这些界值可以得到两个界值的使用:

考虑一个复合的多键索引;即,其中索引字段之一是数组。例如,一个集合survey包含带有一个字段item和一个数组字段的文档 ratings:

在item字段和ratings字段上创建:

上述位于标量字段item和数组字段ratings:

如果数组包含嵌入的文档,要对嵌入文档中包含的字段进行索引,请使用索引规范中的。例如,给定以下嵌入文档数组:

然而,为了复合“评级”的界限。带有“ratings.by”边界的“score”。查询必须使用。有关更多信息,请参见 。

对于嵌入文档中的字段,,例如**“a.b.c”.d"**,是d的字段路径。要复合同一个数组的索引键的边界,必须在到但不包括字段名本身的路径上;即.“a.b.c”。

字段"ratings.score"和"ratings.by"共享字段路径ratings。以下查询使用的字段ratings,以要求所述阵列包含至少有一个元素匹配这两个条件:

如果查询没有将索引数组字段的条件与h连接起来,MongoDB就不能复合它们的边界。考虑以下查询:

如果查询没有在嵌入字段的路径上指定,最多但不包括字段名,MongoDB不能复合来自同一数组的索引键的边界。

在ratings.scores.q1和ratings.scores.q2字段上创建一个。

字段"ratings.scores.q1"和"ratings.scores.q2"共享字段路径"ratings.scores",并且必须在该路径上。

但是,下面的查询使用了,但不是在必需的路径上:

因此,MongoDB 无法混合边界,并且 "ratings.scores.q2"在索引扫描期间该字段将不受限制。要增加界限,查询必须在路径上使用"ratings.scores":

$elemMatch
$elemMatch
复合索引
复合索引
复合索引
复合索引
虚线字段名
$elemMatch
数组中索引字段的复合边界
虚线字段名
$elemMatch
$elemMatch
$elemMatch
$elemMatch
复合索引
$elemMatch
$elemMatch
$elemMatch
索引
多键索引
多键索引
$elemMatch
索引
多键索引
$elemMatch
$elemMatch
多键索引的交集边界
多键索引的复合边界