Mongodb数组字段索引之多键索引

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第92篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关注威赞。谢谢。

Mongodb字段允许包含字符,文档,数组等各种各样的类型。同样Mongodb索引也可以支持字符,文档,数组等类型。本文结合Mongodb官方文档,介绍Mongodb数组类型数据的索引——多键索引。如果应用经常查询数组字段,为该字段添加多键索引,能够提高查询效率,增加索引查询覆盖率,优化数据库查询性能。

如在学生集合当中,包含了存储学生测验成绩的test_scores字段,这个学期的每一次测验成绩都会在这个数组当中。老师需要查询出至少5次测验成绩超过90分的学生 。这样就可以在字段test_scores上添加索引来提高查询效率。因为test_scores是数组类型,Mongodb自动为数组类型创建多键索引。

概述

多键索引,包含并排序了字段中的数组数据。多键索引,能够改善数组字段的查询性能。用户不需要显示的定义多键索引类型。当Mongodb构建索引时,看到该字段是数组字段,就会自动的创建多键索引。Mongodb可以为普通类型数据数组(如字符串数组,数字数组)和嵌入式文档数据来构建多键索引。如果一个数组包含相同值的多个元素,则Mongodb只会选择这些元素中的一个来放入索引当中。

下面的图中描述了多键索引的结构。有一个collection集合,字段addr是文档类型的数组。现在为addr数组中的zip字段建立索引。在索引当中,数组元素的数值从小到大排列。

语法

使用下面的语句来创建多键索引

db.<collection>.createIndex({<arrayField>: <sortOrder>})

使用和限制

索引边界

在查询中,边界定义了索引扫描的各个部分。Mongodb在多键索引边界计算上有特殊的规则,详细查看文档《Mongodb多键索引边界》。

唯一多键索引

在唯一多键索引当中,文档的数组元素,只能包含集合中其他文档数组中不存在的元素。

复合多键索引

在复合多键索引中,每一个文档最多只能包含一个被索引的数组字段。

用户不可以为多个数组创建索引。如在集合中包含了下面一个文档数据

{_id: 1, scores_spring:[8, 6], scores_fall:[5,9]}

其中字段scores_spring和字段scores_fall是数组索引,用户不能够使用{scores_spring: 1, scores_fall:1}来创建索引。

如果一个复合索引已经存在,用户也不能够插入还是索引定义相违背的文档数据。

如集合中包含文档

{_id: 1, scores_spring:[8, 6], scores_fall:9}
{_id: 2, scores_spring:6, scores_fall:[5, 7]}

用户可以创建一个复合多键索引{scores_spring: 1, scores_fall:1},因为每一个文档当中,只有一个字段是数组索引,不包含这两个字段同时是数组字段的文档数据。该索引创建后,Mongodb不允许用户插入两个字段都是数据元素的文档。

排序

基于数组字段的索引进行排序时,满足下面两个条件,才会使用索引排序,而不会在查询中包含一个内存排序。

  • 所有排序字段的值包含在索引边界最大最小值内
  • 任何一个与排序模版带有相同前缀的多键索引都不能有边界限制。这句话在文档中很绕口。尝试去理解一下。如前面提到的索引{scores_spring: 1, scores_fall:1}。当某个查询排序,使用{sort:{scores_spring:1}},这该排序字段是索引{scores_spring: 1, scores_fall:1}的索引前缀。在查询当中,不能对scores_spring做边界限制,否者将使用内存排序。

分片集合

多键索引的字段,不能作为分片键。但是,当分片键是复合索引的前缀时,后续索引字段包含数组时,这个复合索引就会成为一个符合多键索引。

如下文档, 集合中带有索引{field2:1, field1: 1},当使用field2字段作为分片集的关键字时,则field2既是分片关键字,也是复合索引的前缀。外国人写的这些英语,还是很绕的,要理解一下。

{_id:1, field1: [2,8],field2: 'A'}

哈希索引

哈希索引,不能是多键索引

索引覆盖查询

多键索引不能覆盖数组字段的查询。但是,多键索引,能够使用索引前缀,覆盖非数组字段的查询。如下面的一个使用案例。

在集合matches中插入文档。

db.matches.insertMany([{ name: "joe", event: ["open", "tournament"]},{ name: "bill", event: ["match", "championship"]}
])

在name字段和event字段建立索引

db.matches.createIndex({name: 1,event: 1
})

该索引是复合多键索引,但是能够覆盖在name字段的查询

db.matches.find({name: "joe"
}).explain()

使用数组作为查询条件

当查询过滤器中,使用整个数组做为查询条件时,Mongodb能够使用多键索引,查询数组过滤条件中的第一个数组元素,但不能使用多键索引去查询整个数组。当Mongodb使用多键索引查询过滤数组中的第一个元素以后所查询出来的文档,Mongodb在内存中会对这部分文档进一步过滤,过滤出复合查询条件中整个数组的文档。

举例说明一下这个过程。创建集合inventory并插入数据

db.inventory.insertMany([{ _id:5, type: "food", item:"apple", ratings: [ 5, 8, 9 ] },{ _id:6, type: "food", item:"banana", ratings: [ 5, 9 ] },{ _id:7, type: "food", item:"grapes", ratings: [ 9, 5, 8 ] },{ _id:8, type: "food", item:"orange", ratings: [ 5, 9, 5 ] },{ _id:9, type: "food", item:"pear", ratings: [ 9, 5 ] }
])

在数组ratings建立多键索引

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

构建一个使用数组作为过滤器的查询语句

db.inventory.find({ratings: [5, 9]
})

在查询计划中,能够看出,mongodb先使用5通过多键索引,查询出所有包含元素5的文档,然后在内存中过滤出包含整个数组[5,9]的文档数据

$expr

$expr表达式,不支持多键索引

应用

为数值数组添加索引

创建students集合,并插入数据。其中 test_scores是数值类型的数组。

db.students.insertMany([{name: 'Andre Robinson', test_scores: [88, 97]},{name: 'Alice Martin', test_scores: [62, 73]},{name: 'Bob Smith', test_scores: [92, 89]}
])

用户经常需要查询出至少有一次测验分数大于90的同学,这可以向数组字段添加索引来提高性能

db.students.createIndex({test_scores: 1})

因为字段test_scores是数组类型,所以Mongodb自动为该字段创建了多键索引。该索引中包含了字段test_scores的所有值,并按照从小到大排列,[62, 73, 88, 89, 92, 97].该索引支持在字段test_scores上的查询

db.students.find({test_scores: { $elemMatch: { $gte: 90 } }
})

为文档数组添加索引

构建inventory集合并插入数据

db.inventory.insertMany([{item: "t-shirt",stock: [{ size: "S", quantity: 8 },{ size: "L", quantity: 10 }]},{item: "sweater",stock: [{ size: "S", quantity: 4 },{ size: "M", quantity: 7 }]},{item: "vest",stock: [{ size: "S", quantity: 6 },{ size: "L", quantity: 1 }]}
])

用户需要在库存低于5的时候,下订单来补货。为了查找出哪些需要补货,需要构建语句,查出来stock数组中,数量quantity少于5的记录。为了提高性能,用户需要在字段stock.quantity上添加索引。

db.inventory.createIndex({'stock.quantity': 1})

因为stock是包含文档的数组,索引Mongodb将这个索引存储为多键索引。该索引将字段stock.quantity所有值按照从小到大排列[1,4,6,7,8,10]

构建语句,查询出少于5的数据

db.inventory.find({'stock.quantity': { $lt: 5 }})

查询数据,按照库存的倒序排列

db.inventory.find().sort({'stock.quantity': -1})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/47147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【中项第三版】系统集成项目管理工程师 | 第 5 章 软件工程② | 5.4 - 5.8

前言 第 5 章对应的内容选择题和案例分析都会进行考查&#xff0c;这一章节属于技术的内容&#xff0c;学习要以教材为准。 目录 5.4 软件实现 5.4.1 软件配置管理 5.4.2 软件编码 5.4.3 软件测试 5.5 部署交付 5.5.1 软件部署 5.5.2 软件交付 5.5.3 持续交付 5.5.4…

Java语言程序设计——篇五

数组 概述数组定义实例展示实战演练 二维数组定义数组元素的使用数组初始化器实战演练&#xff1a;矩阵计算 &#x1f4ab;不规则二维数组实战演练&#xff1a;杨辉三角形 概述 ⚡️数组是相同数据类型的元素集合。各元素是有先后顺序的&#xff0c;它们在内存中按照这个先后顺…

论文分享|AAAI2024‘北航|软标签监督实现通用密集检索——图文检索中的跨模态和单模态软标签对齐

论文题目&#xff1a;Cross-Modal and Uni-Modal Soft-Label Alignment for Image-Text Retrieval 来源&#xff1a;AAAI2024/实验室师兄/北航 方向&#xff1a;跨模态检索 开源地址&#xff1a;https://github.com/lerogo/aaai24_itr_cusa 摘要 近年来&#xff0c;目前的…

保障低压设备安全!中国星坤连接器精密工艺解析!

在现代电子设备中&#xff0c;连接器扮演着至关重要的角色&#xff0c;它们是电子系统之间沟通的桥梁。随着技术的发展&#xff0c;对连接器的需求也在不断提升&#xff0c;特别是在低电压应用领域。中国星坤最新推出的低压连接器&#xff0c;以其精密性和安全性&#xff0c;为…

Kafka Producer发送消息流程之分区器和数据收集器

文章目录 1. Partitioner分区器2. 自定义分区器3. RecordAccumulator数据收集器 1. Partitioner分区器 clients/src/main/java/org/apache/kafka/clients/producer/KafkaProducer.java&#xff0c;中doSend方法&#xff0c;记录了生产者将消息发送的流程&#xff0c;其中有一步…

书生浦语-大模型平台学习-环境搭建01

任务&#xff1a;完成SSH连接与端口映射并运行hello_world.py 详细步骤详见&#xff1a;https://github.com/InternLM/Tutorial/blob/camp3/docs/L0/Linux/readme.md 1、InternStudio介绍 InternStudio 是大模型时代下的云端算力平台。基于 InternLM 组织下的诸多算法库支持…

CentOS快速安装Docker(腾讯镜像源)

这里是引用"> 1、卸载旧版本的 Docker yum list installed | grep docker yum -y remove docker-ce-cli.x86_64 yum -y remove docker-ce.x86_64 yum -y remove containerd.io2、安装相关依赖 yum install -y yum-utils device-mapper-persistent-data lvm23、添加 …

嵌入式人工智能(9-基于树莓派4B的PWM-LED呼吸灯)

1、PWM简介 (1)、什么是PWM 脉冲宽度调制(PWM)&#xff0c;是英文“Pulse Width Modulation”的缩写&#xff0c;简称脉宽调制&#xff0c;是在具有惯性的系统中利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术&#xff0c;广泛应用在从测量、通信到功率控制…

学习大数据DAY17 PLSQL基础语法6和Git的基本操作

目录 包 存储过程调试功能 作业 阶段复习作业 Git课程目录 什么是版本控制 没有版本控制的缺点 常见的版本工具 版本控制分类 1. 本地版本控制 2. 集中版本控制 3. 分布式版本控制 Git与SVN主要区别 Git软件安装及配置 Windows系统安装Git 安装Tortoise Git(乌龟…

降Compose十八掌之『震惊百里』| Animations

公众号「稀有猿诉」 原文链接 降Compose十八掌之『震惊百里』| Animations 动画对于UI来说无疑是最重要的核心功能&#xff0c;它能够让UI变得生动有吸引力。适当的使用动画可以提升UI的流畅性&#xff0c;让UI体验更为顺滑。在Jetpack Compose中有丰富的函数可以用来实…

六西格玛设计:以客户为中心,驱动企业持续创新

在当今竞争激烈的市场环境中&#xff0c;企业要想脱颖而出&#xff0c;就必须在产品质量、服务效率和客户满意度上不断追求卓越。六西格玛设计&#xff08;Six Sigma Design&#xff09;作为一种高度规范化的管理方法&#xff0c;正逐步成为众多企业实现这一目标的重要工具。张…

NSSCTF中24网安培训day2中web题目【下】

[NISACTF 2022]easyssrf 这道题目考察的是php伪协议的知识点 首先利用file协议进行flag查找 file:///flag.php 接着我们用file协议继续查找fl4g file:///fl4g 接着我们访问此文件&#xff0c;得到php代码如下 这里存在着stristr的函数&#x…

Linux中的环境变量

一、基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#xff0c;但是照样可以链接成功&#xff…

Cesium能做啥,加载哪些数据源,开源免费用商用吗?这里告诉你。

很多小伙伴对Cesium是什么&#xff0c;一知半解&#xff0c;本文是基础知识的扫盲&#xff0c;为大家分享cesium是什么、能做什么、默认数据是什么&#xff0c;为什么首先要进行数据加载&#xff0c;要加载哪些数据&#xff0c;希望通过这些带你入个门&#xff0c;欢迎点赞评论…

vue仿甘特图开发工程施工进度表

前言 本文是根据项目实际开发中一个需求开发的demo&#xff0c;仅用了elementUI&#xff0c;可当作独立组件使用&#xff0c;C V即用。 当然没考虑其他的扩展性和一些数据的校验&#xff0c;主要是提供一个处理思路&#xff0c;有需要的小伙伴可以直接复制&#xff1b;本demo的…

高职院校人工智能人才培养成果导向系统构建、实施要点与评量方法

一、引言 近年来&#xff0c;人工智能技术在全球范围内迅速发展&#xff0c;对各行各业产生了深远的影响。高职院校作为培养高技能人才的重要基地&#xff0c;肩负着培养人工智能领域专业人才的重任。为了适应社会对人工智能人才的需求&#xff0c;高职院校需要构建一套科学、…

【node-RED 4.0.2】连接 Oracle 数据库踩坑解决,使用模组:node-red-contrib-agur-connector

关于 Oracle Oracle 就好像一张吸满水的面巾纸&#xff0c;你稍一用力它就烂了。 PS&#xff1a;我更新了更好的模组的教程&#xff0c;这篇已经是旧款的教程&#xff0c;但是它仍旧包含了必要的配置环境变量等操作。 最新的模组教程&#xff1a;node-red-contrib-agur-connec…

AI时代:探索个人潜能的新视角

文章目录 Al时代的个人发展1 AI的高速发展意味着什么1.1 生产力大幅提升1.2 生产关系的改变1.3 产品范式1.4 产业革命1.5 Al的局限性1.5.1局限一:大模型的幻觉1.5.2 局限二&#xff1a;Token 2 个体如何应对这种改变?2.1 职场人2.2 K12家长2.3 大学生2.4 创业者 3 人工智能发展…

解决vue3中el-input在form表单按下回车刷新页面

问题&#xff1a;在input框中点击回车之后不是调用我写的回车事件&#xff0c;而是刷新页面 原因&#xff1a; 如果表单中只有一个input 框则按下回车会直接关闭表单 所以导致刷新页面 解决方法 &#xff1a; 再写一个input 表单 &#xff0c;并设置style"display:none&…

SimMIM:一个类BERT的计算机视觉的预训练框架

1、前言 呃…好久没有写博客了&#xff0c;主要是最近时间比较少。今天来做一期视频博客的内容。本文主要讲SimMIM&#xff0c;它是一个将计算机视觉&#xff08;图像&#xff09;进行自监督训练的框架。 原论文&#xff1a;SimMIM&#xff1a;用于掩码图像建模的简单框架 (a…