Mongodb查询投射中使用$符号

2024-01-28 16:12

本文主要是介绍Mongodb查询投射中使用$符号,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

数组是mongodb文档类型中一个重要的类型。mongodb查询当中,往往要按照要求,返回数组中的元素。在投射中使用$符号,返回符合查询条件的第一个数组元素。

定义

数组定位符号$,限定返回数组中第一个匹配查询条件的数组元素。当用户只想返回数组中一个指定元素时,在find()或findOne()方法的投射文档中,在数组字段后添加.$符号。

使用注意事项

  • 在投射中,使用$和$elemMatch操作符,都可以按照指定查询条件,返回数组中第一个匹配的元素。
  • 使用$符号时,按照用户定义的查询条件返回第一个数组文档。
  • 使用$elemMatch操作符时,用户可以显示的重新定义过滤条件。允许用户在投射文档中,添加查询条件中不存在的字段。也允许用户基于嵌套文档数组类型中多个字段,构建过滤条件。
  • 视图查询中,不支持投射中使用$符号。

语法

返回符合查询条件的第一个数组元素

db.collection.find({<array>: <condition> ...,}, //数组查询条件{"<array.$>": 1} //投射中使用$符号
)db.collection.find({<array.field>: <condition> ...,}, //嵌套文档数组中,使用文档字段作为查询条件{"<array.$>": 1} //投射中使用$符号
)

注意版本4.4前后的差异。4.4版本前,在查询条件中,必须有数组定义。而在4.4版本以后,无需这样的要求。

db.collection.find({<someOtherArray>: <condition> ...},//定义其他数组{"<array>.$": 1}
)

当在投射使用$符号时,查询文档中的数组必须与投射中使用的数组具有相同的长度。若长度不同,在某些场景中会报错。

投射中使用$时数组字段限制

在对数组进行投射时,mongodb有下面的限制。

  • 投射文档中只能出现一个$符号
  • 查询文档中只能出现一个数组查询条件。多余的查询条件可能因此未知的行为。如下面的查询语句,可能引起未知的行为
db.collection.find( { <array>: <value>, <someOtherArray>: <value2>},{"<array>.$": 1})
  • 对嵌套文档数组的查询条件,应该只包含一个字段的查询条件。多个查询条件在mongodb内部会被覆盖而导致位置错误。通过$elemMatch查询操作符,指定多个字段的查询条件。下面的查询语句中,返回了grades数组中,mean字段大于70,grade字段大于90的数据。
db.students.find( {grades: {$elemMatch: {mean: {$gt: 70},grade: {$gt: 90}}
}}, {"grades.$": 1
})

当使用多个查询条件时,需要使用$elemMatch操作符。

排序和$操作符

在find()查询中包含排序时,sort()操作符执行先于$投射操作符。当查询文档中包含多个相同字段的查询条件并且sort中也包含这个重复的字段时,返回结果可能无法反映正确的排序。因为排序在$投射前发生。

$操作符的限制

4.4版本以后,投射中的$操作符,只能位于投射字段定义中的最后。

如下面的语句中,$符号位置是错误的。

db.inventory.find({}, {"instock.$.qty": 1})

为了解决这个错误,删除$后的'.qty'。

在前面的版本中,mongodb会忽略$符号后面的字段定义。按照"instock.$"来返回。

$操作符和$slice

4.4版本以后,find与findAndModify投射定义中,不可以包含$slice。

下面的语句是错误的

db.inventory.find({"instock.qty": {$gt: 25}}, {"instock.$": {$slice: 1}})

应用举例

构建测试集合students.向集合中插入5条数据,其中grades字段是数组类型,包含三个数字的数组。

db.students.drop()
db.students.insertMany([{ "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] },{ "_id" : 2, "semester" : 1, "grades" : [ 90, 88, 92 ] },{ "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] },{ "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] },{ "_id" : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] },{ "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] }
])

查询第一学期中,grades大于等于85的学生记录。在返回文档中,返回第一个匹配的grades数据

db.students.find({semester: 1, grades: {$gte: 85}},{"grades.$": 1}
)

向集合中插入另外两条数据。其中grades是文档数组类型的字段。

db.students.insertMany([
{ "_id" : 7, semester: 3, "grades" : [ { grade: 80, mean: 75, std: 8 },{ grade: 85, mean: 90, std: 5 },{ grade: 90, mean: 85, std: 3 } ] },
{ "_id" : 8, semester: 3, "grades" : [ { grade: 92, mean: 88, std: 8 },{ grade: 78, mean: 90, std: 5 },{ grade: 88, mean: 85, std: 3 } ] }
])

查询mean大于70的学生数据,返回第一个匹配的grades数据

db.students.find({semester: 3, 'grades.mean': {$gt: 70}},{"grades.$": 1})

这篇关于Mongodb查询投射中使用$符号的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/654129

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他