Mongodb文档和数组的通配符索引

news/2024/9/22 16:03:10/

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第97篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关注威赞。谢谢。威赞文章都是结合官方文档,翻译整理而来,并对每个知识点的描述都认真思考和实践,对难以理解的地方,使用简单容易理解的方式进行阐述。

概述

Mongodb的通配符索引,为灵活可变的Mongodb数据结构提供了高效的查询方法。本文结合Mongodb官方文档,详细介绍在嵌入式文档和数组上,通配符索引的结构。

Mongodb为嵌入式文档和数组字段建立通配符索引时,有特殊的逻辑:

  • 当为文档对象建立通配符索引时,Mongodb会扫描文档对象的每一个字段,将文档的每一个字段都加入到该通配符索引中。如果该字段值也是文档对象,则继续向下扫描,将该文档类型的字段添加到通配符索引。
  • 当为数组对象建立通配符索引时, Mongodb会扫描数组中的每一个元素,将每一个元素的内容添加到通配符索引。如果该元素是个数组,则将数组整体放入的通配符索引中。当数组元素是对象时,则按照添加对象的方式,将该对象的每一个字段添加到通配符索引。
  • 对于其他类型的字段,通配符索引保存基本的数据类型值。即非对象,非数组类型值。

通配符索引会持续转换构建索引时遇到的嵌套文档或数组,直到遇到基本数值为止。Mongodb将基本数值和该字段的路径,都放入到通配符索引当中。

应用

为文档对象建立通配符索引

构建集合users并插入数据

db.users.insertOne({account: {user_name: "SuperAdmin01",contact: {email: "xyz@example.com",phone: "1234567890"},access: {group: "admin"}}
})

在account字段添加通配符索引

db.users.createIndex({"account.$**": 1})

Mongodb在构建通配符索引时,会解析account对象的每一个字段 ,将每一个字段的值和路径放到索引中

  • "account.username": "SuperAdmin01"
  • "account.contact.email": "xyz@example.com"
  • "account.contact.phone": "1234567890"
  • "access.group": "admin"

为数组对象添加通配符索引

创建fleet集合并添加数据

db.fleet.insertOne({ship: {coordinates: [[ 37.786971, -122.399677 ],[ 37.786971, -122.399677 ]],type: "Cargo Ship",captains: [{name: "John Doe",age: 45,crew: [ "first mate", "engineer" ]}]}
})

为ship字段添加索引

db.fleet.createIndex({"ship.$**": 1})

ship字段包含一个数组类型的字段coordinates, 字符类型的字段type, 数组类型的字段captains. 其中数组字段coordinates的元素也是数据,在构建通配符索引时,直接将coordinates字段的数组放入索引当中。captains是文档类型的数据,Mongodb构建通配符索引时,会进一步解析到基本元素,将基本元素放入索引当中。按照这样的规则 ,索引当中,存在下面的数据

  • "ship.coordinates":[37.786971, -122.399677 ],
  • "ship.coordinates":[37.786971, -122.399677 ],
  • "ship.type":"Cargo Ship",
  • "ship.captains.name":"John Doe",
  • "ship.captains.age":45,
  • "ship.captains.crew":"first mate",
  • "ship.captains.crew":"first engineer"

从上面的例子当中可以看到,在构建索引时,并没有把元素在数组中的位置也添加到索引当中。但mongdb也能够使用通配符索引,支持带有数组元素位置的查询。如

db.fleet.find({"ship.captains.0.age": {$gt: 40}})

查看该查询的执行计划

但通配符索引,不支持下面的查询

db.fleet.find({"ship.coordinates.0.1": 37.786971
})

查看执行计划,能够看到使用全表扫描,而不是通配符索引。因为通配符索引将整个数组元素作为整体放倒索引数据中。而用户使用数组当中的一个值来查询时,Mongodb选择了全表扫描。

Mongodb在构建通配符索引时,不会限制文档数组类型结构的深度。但查询时,如果路径长度超过8, Mongodb会选择其他更高效的索引或全表扫描的方式。


http://www.ppmy.cn/news/1500115.html

相关文章

LangChain--如何使用大模型

【🍊易编橙终身成长社群🍊】 大家好,我是小森( ﹡ˆoˆ﹡ ) ! 易编橙终身成长社群创始团队嘉宾,橙似锦计划领衔成员、阿里云专家博主、腾讯云内容共创官、CSDN人工智能领域优质创作者 。 LangCha…

用代理IP会频繁掉线是什么原因?HTTP和SOCKS5协议优劣势是什么?

在使用代理IP的过程中,频繁掉线是一个常见且令人头痛的问题。要解决这一问题,我们需要先了解其原因,然后比较HTTP和SOCKS5两种代理协议的优劣势,以选择最适合的解决方案。 一、代理IP频繁掉线的原因 1. 代理服务器稳定性 代理服…

rk3588s 定制版 USB adb , USB2.0与USB3.0 区别,adb 由typeC 转换到USB3.0(第二部分)

硬件资源: rk3588s 核心板定制的地板 软件资源: 网盘上的 android12 源码 1 硬件上 客户只想使用 type c 接口中的 usb2.0 OTG 。在硬件上,甚至连 CC芯片都没有连接。 关于一些前置的知识。 1 USB2.0 与 USB3.0 的区别。 usb3.0 兼容2.0 …

python库(14):Arrow库简化时间处理

1 Arrow简介 Arrow 是一个被称为程序员的时间处理利器的 Python 库。 从诞生起,它就是为了填补 Python 的 datetime 类型的功能空白而生的。为程序员提供了一种更简单、更直观的方式来处理日期和时间。 2 安装Arrow库 pip install arrow -i https://pypi.tuna.ts…

科普文:分布式数据一致性协议Paxos

1 什么是Paxos Paxos协议其实说的就是Paxos算法, Paxos算法是基于消息传递且具有高度容错特性的一致性算 法,是目前公认的解决分布式一致性问题最有效的算法之一。 Paxos由 莱斯利兰伯特(Leslie Lamport)于1998年在《The Part-Time Parliament》论文中首次公 开&…

【嵌入式开发 Linux 常用命令系列 7.7 -- find 和 sed 配合使用介绍】

请阅读【嵌入式及芯片开发学必备专栏】 文章目录 使用背景注意事项使用示例 使用背景 当时想在 linux 环境下 使用 find 命令找到 .c 和 .h 文件,并使用xargs 加 sed 命令将文件中所有"demo" 字符串替换为 “hello” 命令实现: 使用 find 命…

鸿蒙开发仓颉语言【在工程中使用Hyperion TCP框架】

3. 在工程中使用Hyperion TCP框架 3.1 导入Hyperion TCP框架的静态库 在工程的module.json中引入Hyperion TCP框架的静态库: "package_requires": {"package_option": {"hyperion_hyperion.buffer": "${path_to_hyperion_proj…

Django进阶学习教程

目录 Django进阶学习详细教程1. Django中间件和信号1.1 中间件的创建和应用示例:创建简单中间件应用中间件 1.2 信号的使用场景和实现示例:使用信号注册信号 2. Django静态文件和缓存2.1 静态文件的配置和使用示例:配置静态文件使用静态文件 …