MongoDB聚合管道数组操作

数组表达式运算符判断数组中是否包含元素( i n ) 并获取元素索引 ( in)并获取元素索引( in)并获取元素索引(indexOfArray)

一、初始化成员数据

db.persons.insertMany([{ "_id" : "1001", "name" : "张三", "fruits" : [ "apple", "orange" ] },{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] },{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] },{ "_id" : "1004", "name" : "赵六", "fruits" : [ ] },{ "_id" : "1005", "name" : "田七" },
])

二、包含元素($in)

语法:{ $in: [ , ] }

判断数组中是否包含某个元素

expression:代表的是元素

array expression:代表的是数组

例子:判断成员是否喜欢苹果

db.persons.aggregate([{$project: {"name": 1,"favoriteApple": {$in: [ "apple", "$fruits" ]}}}
])

聚合查询的结果如下:

{"ok" : 0,"errmsg" : "$in requires an array as a second argument, found: missing","code" : 40081,"codeName" : "Location40081"
}

发现报错了,原因是在编号为1005的成员中不存在fruits字段导致的。

这里我们需要**使用 i s A r r a y 断言数组操作进行聚合查询 < / f o n t > ∗ ∗ < f o n t s t y l e = " c o l o r : r g b ( 77 , 77 , 77 ) ; " > ,如果您对 isArray断言数组操作进行聚合查询</font>**<font style="color:rgb(77, 77, 77);">,如果您对 isArray断言数组操作进行聚合查询</font><fontstyle="color:rgb(77,77,77);">,如果您对isArray断言数组操作不太了解,可以参考:https://blog.csdn.net/m1729339749/article/details/130162535

下面我们使用$isArray断言数组操作改进聚合查询:

db.persons.aggregate([{$project: {"name": 1,"favoriteApple": {$cond: {if: { $isArray: "$fruits" }, then: { $in: [ "apple", "$fruits" ] }, else: false}}}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "favoriteApple" : true }
{ "_id" : "1002", "name" : "李四", "favoriteApple" : true }
{ "_id" : "1003", "name" : "王五", "favoriteApple" : true }
{ "_id" : "1004", "name" : "赵六", "favoriteApple" : false }
{ "_id" : "1005", "name" : "田七", "favoriteApple" : false }

三、获取元素索引($indexOfArray)

语法:{ $indexOfArray: [ , , , ] }

查询元素在数组中的索引位置

array expression:代表的是数组

search expression:代表的是待搜索的元素

start:可选,搜索的起始位置

end:可选,搜索的结束位置

搜索的范围是 [start, end) 即前开后闭

例子1:搜索水果apple的索引

db.persons.aggregate([{$project: {"name": 1,"indexApple": {$indexOfArray: [ "$fruits", "apple" ]}}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "indexApple" : 0 }
{ "_id" : "1002", "name" : "李四", "indexApple" : 1 }
{ "_id" : "1003", "name" : "王五", "indexApple" : 1 }
{ "_id" : "1004", "name" : "赵六", "indexApple" : -1 }
{ "_id" : "1005", "name" : "田七", "indexApple" : null }

未查找到元素,返回-1

数组字段不存在,返回null

例子2:搜索水果apple的索引,起始位置(0)结束位置(1)

db.persons.aggregate([{$project: {"name": 1,"indexApple": {$indexOfArray: [ "$fruits", "apple", 0 ,1 ]}}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "indexApple" : 0 }
{ "_id" : "1002", "name" : "李四", "indexApple" : -1 }
{ "_id" : "1003", "name" : "王五", "indexApple" : -1 }
{ "_id" : "1004", "name" : "赵六", "indexApple" : -1 }
{ "_id" : "1005", "name" : "田七", "indexApple" : null }

与例子1中聚合查询的结果比较我们会发现:

编号为1002,1003的成员数据中没有检索到元素,说明检索的范围不包含结束位置对应的索引。

start,end检索的范围是[start, end),包含起始位置对应的索引,不包含结束位置对应的索引

数组表达式运算符截取数组($slice)

数组表达式运算符主要用于文档中数组的操作,本篇我们主要介绍数组表达式运算符中用于截取数组的操作,下面我们进行详细介绍:

一、语法

{ $slice: [ , ] }

或者 { $slice: [ , , ] }

获取数组中指定范围内的元素组成一个新的数组

:代表的是数组

:代表的是起始位置索引(包含此位置的元素)

:代表的是获取N个元素

二、准备工作

初始化成员数据

db.persons.insertMany([{ "_id" : "1001", "name" : "张三", "fruits" : [ "apple", "pineapple", "orange" ] },{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple", "pineapple" ] },{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange", "watermelon" ] },{ "_id" : "1004", "name" : "赵六", "fruits" : [ ] },{ "_id" : "1005", "name" : "田七" },
])

三、示例

例子1:找到每个人最喜欢吃的前两个水果

db.persons.aggregate([{$project: {"name": 1,"favoriteFruits": { $slice: [ "$fruits", 2 ] }}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "favoriteFruits" : [ "apple", "pineapple" ] }
{ "_id" : "1002", "name" : "李四", "favoriteFruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "favoriteFruits" : [ "banana", "apple" ] }
{ "_id" : "1004", "name" : "赵六", "favoriteFruits" : [ ] }
{ "_id" : "1005", "name" : "田七", "favoriteFruits" : null }

例子2:找到每个人最喜欢吃的最后两个水果

db.persons.aggregate([{$project: {"name": 1,"favoriteFruits": { $slice: [ "$fruits", -2 ] }}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "favoriteFruits" : [ "pineapple", "orange" ] }
{ "_id" : "1002", "name" : "李四", "favoriteFruits" : [ "apple", "pineapple" ] }
{ "_id" : "1003", "name" : "王五", "favoriteFruits" : [ "orange", "watermelon" ] }
{ "_id" : "1004", "name" : "赵六", "favoriteFruits" : [ ] }
{ "_id" : "1005", "name" : "田七", "favoriteFruits" : null }

(1)****字段未定义时,结果为null;

(2)未找到元素,结果为[ ]

(3){ $slice: [ , ] } 语法中 n为正数,代表的是从前往后取N个元素,n为负数,代表的是从后往前取N个元素

例子3:找到每个人最喜欢吃的第二个水果

db.persons.aggregate([{$project: {"name": 1,"favoriteFruits": { $slice: [ "$fruits", 1, 1 ] }}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "favoriteFruits" : [ "pineapple" ] }
{ "_id" : "1002", "name" : "李四", "favoriteFruits" : [ "apple" ] }
{ "_id" : "1003", "name" : "王五", "favoriteFruits" : [ "apple" ] }
{ "_id" : "1004", "name" : "赵六", "favoriteFruits" : [ ] }
{ "_id" : "1005", "name" : "田七", "favoriteFruits" : null }

例子4:假如position为负数,会如何处理

db.persons.aggregate([{$project: {"name": 1,"favoriteFruits": { $slice: [ "$fruits", -2, 1 ] }}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "favoriteFruits" : [ "pineapple" ] }
{ "_id" : "1002", "name" : "李四", "favoriteFruits" : [ "apple" ] }
{ "_id" : "1003", "name" : "王五", "favoriteFruits" : [ "orange" ] }
{ "_id" : "1004", "name" : "赵六", "favoriteFruits" : [ ] }
{ "_id" : "1005", "name" : "田七", "favoriteFruits" : null }

例子5:假如position = -10,会如何处理

db.persons.aggregate([{$project: {"name": 1,"favoriteFruits": { $slice: [ "$fruits", -10, 1 ] }}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "favoriteFruits" : [ "apple" ] }
{ "_id" : "1002", "name" : "李四", "favoriteFruits" : [ "banana" ] }
{ "_id" : "1003", "name" : "王五", "favoriteFruits" : [ "banana" ] }
{ "_id" : "1004", "name" : "赵六", "favoriteFruits" : [ ] }
{ "_id" : "1005", "name" : "田七", "favoriteFruits" : null }

如果position为负数,则从后往前确定起始位置,当向前移动的位置超过了数组长度,则起始位置为0;然后再从前往后获取N个元素组成新的数组。

数组表达式运算符过滤数组($filter)

数组表达式运算符主要用于文档中数组的操作,本篇我们主要介绍数组表达式运算符中用于过滤数组的操作,下面我们进行详细介绍:

一、语法

{$filter:{input: <array>,cond: <expression>,as: <string>,limit: <number expression>}
}

其中,

input:代表的是数组

cond:代表的是条件

as:可选,定义的变量,用于接收数组中的当前元素,如果未定义在cond表达式中可以使用$$this获取数组中的当前元素

limit:可选,限制数组中元素的个数

二、准备工作

初始化零食数据

db.goods.insertMany([{ "_id" : 1, "name" : "薯片", "types" : [ { "size" : "S", "quantity" : 10, "price" : 8 },{ "size" : "L", "quantity" : 8, "price" : 12 } ]},{ "_id" : 2, "name" : "牛肉干", "types" : [ { "size" : "L", "quantity" : 5, "price" : 30} ]},{ "_id" : 3, "name" : "可口可乐", "types" : [ { "size" : "S", "quantity" : 10, "price" : 3 }, { "size" : "L", "quantity" : 6, "price" : 10 } ]},{ "_id" : 4, "name" : "旺仔牛奶", "types" : [ { "size" : "L", "quantity" : 10, "price" : 5 } ]}
])

三、示例

例子1:只查看型号为L的型号信息

db.goods.aggregate([{$project: {types: {$filter: {input: "$types",cond: { $eq: [ "$$this.size", "L" ] }}}}}
])

等效于:

db.goods.aggregate([{$project: {types: {$filter: {input: "$types",as: "type",cond: { $eq: [ "$$type.size", "L" ] }}}}}
])

聚合查询的结果如下:

{ "_id" : 1, "types" : [ { "size" : "L", "quantity" : 8, "price" : 12 } ] }
{ "_id" : 2, "types" : [ { "size" : "L", "quantity" : 5, "price" : 30 } ] }
{ "_id" : 3, "types" : [ { "size" : "L", "quantity" : 6, "price" : 10 } ] }
{ "_id" : 4, "types" : [ { "size" : "L", "quantity" : 10, "price" : 5 } ] }

as用于定义一个存储数组中当前元素的变量,使用变量时前面需要加上 “$$”;

如果不使用as定义变量,也可以使用 $$this 访问数组中的当前元素

例子2:对超过5元的型号进行查询

db.goods.aggregate([{$project: {types: {$filter: {input: "$types",as: "type",cond: { $gt: [ "$$type.price", 5 ] }}}}}
])

聚合查询的结果如下:

{ "_id" : 1, "types" : [ { "size" : "S", "quantity" : 10, "price" : 8 }, { "size" : "L", "quantity" : 8, "price" : 12 } ] }
{ "_id" : 2, "types" : [ { "size" : "L", "quantity" : 5, "price" : 30 } ] }
{ "_id" : 3, "types" : [ { "size" : "L", "quantity" : 6, "price" : 10 } ] }
{ "_id" : 4, "types" : [ ] }

多个查询条件

cond: {$and: [{ $gte: ['$$item.timestamp_start', fromTimestamp] },{ $lt: ['$$item.timestamp_start', toTimestamp] }]
}

数组表达式运算符( a r r a y E l e m A t , arrayElemAt, arrayElemAtfirst,$last)

数组表达式运算符主要用于文档中数组的操作,本篇我们主要介绍数组表达式运算符中用于获取数组元素的操作,下面我们进行详细介绍:

一、准备工作

初始化成员数据

db.persons.insertMany([{ "_id" : "1001", "name" : "张三", "fruits" : [ "apple", "orange" ] },{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] },{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] },{ "_id" : "1004", "name" : "赵六", "fruits" : [ ] },{ "_id" : "1005", "name" : "田七" },
])

二、获取数组中指定元素($arrayElemAt)

语法:{ $arrayElemAt: [ , ] }

获取数组中指定索引位置的元素

:代表的是数组

:代表的是索引,索引为正数代表的是从前往后查找元素、为负数代表的是从后往前查找元素

数组的索引从0开始,最大值为数组的长度-1

例子1:找到每个人最喜欢吃的第一个水果

db.persons.aggregate([{$project: {"name": 1,"firstFruit": { $arrayElemAt: [ "$fruits", 0 ] }}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "firstFruit" : "apple" }
{ "_id" : "1002", "name" : "李四", "firstFruit" : "banana" }
{ "_id" : "1003", "name" : "王五", "firstFruit" : "banana" }
{ "_id" : "1004", "name" : "赵六" }
{ "_id" : "1005", "name" : "田七", "firstFruit" : null }

字段未定义时,结果为null,

索引超过数组边界则不返回结果。

例子2:找到每个人最喜欢吃的最后一个水果

db.persons.aggregate([{$project: {"name": 1,"lastFruit": { $arrayElemAt: [ "$fruits", -1 ] }}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "lastFruit" : "orange" }
{ "_id" : "1002", "name" : "李四", "lastFruit" : "apple" }
{ "_id" : "1003", "name" : "王五", "lastFruit" : "orange" }
{ "_id" : "1004", "name" : "赵六" }
{ "_id" : "1005", "name" : "田七", "lastFruit" : null }

索引为负数代表的是从后往前查找元素

三、获取数组中第一个元素($first)

语法:{ $first: }

获取数组中第一个元素

例子:找到每个人最喜欢吃的第一个水果

db.persons.aggregate([{$project: {"name": 1,"firstFruit": { $first: "$fruits" }}}
])

等效于:

db.persons.aggregate([{$project: {"name": 1,"firstFruit": { $arrayElemAt: [ "$fruits", 0 ] }}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "firstFruit" : "apple" }
{ "_id" : "1002", "name" : "李四", "firstFruit" : "banana" }
{ "_id" : "1003", "name" : "王五", "firstFruit" : "banana" }
{ "_id" : "1004", "name" : "赵六" }
{ "_id" : "1005", "name" : "田七", "firstFruit" : null }

四、获取数组中最后一个元素($last)

语法:{ $last: }

获取数组中最后一个元素

例子:找到每个人最喜欢吃的最后一个水果

db.persons.aggregate([{$project: {"name": 1,"lastFruit": { $last: "$fruits" }}}
])

等效于:

db.persons.aggregate([{$project: {"name": 1,"lastFruit": { $arrayElemAt: [ "$fruits", -1 ] }}}
])

聚合查询的结果如下:

{ "_id" : "1001", "name" : "张三", "lastFruit" : "orange" }
{ "_id" : "1002", "name" : "李四", "lastFruit" : "apple" }
{ "_id" : "1003", "name" : "王五", "lastFruit" : "orange" }
{ "_id" : "1004", "name" : "赵六" }
{ "_id" : "1005", "name" : "田七", "lastFruit" : null }

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

编写情绪K线指标(附带源码下载)

编写需求&#xff1a; 很多交易者抱怨&#xff0c;传统的跟踪类指标常常存在滞后的问题&#xff0c;而预测类指标又常常不够可靠。那么&#xff0c;是否存在一种指标&#xff0c;能够精准地反映当前K线的强弱变化&#xff0c;并且具备高度的时效性呢&#xff1f; 效果展示&am…

16、pxe自动装机

pxe自动装机的组成 pxe&#xff1a;自动安装系统必要的运行环境 无人值守&#xff1a;为系统定制化的安装需要的软件 pxe的优点 规模化&#xff1a;同时装配多台服务器&#xff08;20-30&#xff09; 自动化&#xff1a;系统安装和服务配置不需要人工干预 远程实现&#x…

H.265流媒体播放器EasyPlayer.js网页直播/点播播放器WebGL: CONTEXT_LOST_WEBGL错误引发的原因

EasyPlayer无插件直播流媒体音视频播放器属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;无须安装任何插件&#xff0c;起播快、延迟低、兼容性强&#xff0c;使用非常便捷。 EasyPlayer.js能够同时支持HTTP、HTTP-FLV、HLS&a…

Javaweb开发核⼼心之玩转Servlet4(笔记)

javaweb开发核⼼心之玩转Servlet4.0 简介&#xff1a;什么是Servlet-开发你的第⼀一个动态⽹网站 什么是Servlet 简介&#xff1a;是JavaServlet的简称&#xff0c;⽤用Java编写的运⾏行行在Web服务器器或应⽤用服务器器上的程序,具有独⽴立于平台和协议的特性, 主要功能在于交…

VUE实现通话:边录边转发送语言消息、 播放pcm 音频

文章目录 引言I 音频协议音频格式:音频协议:II 实现协议创建ws对象初始化边录边转发送语言消息 setupPCM按下通话按钮时开始讲话,松开后停止讲话播放pcm 音频III 第三库recorderplayer调试引言 需求:电台通讯网(电台远程遥控软件-超短波)该系统通过网络、超短波终端等无线…

无人机遥控器基础讲解——CKESC电调小课堂08

无人机遥控器是控制无人机飞行的重要设备&#xff0c;以下是对其的详细介绍&#xff1a; CKESC-专业级电调研发生产供应商http://www.ckesc.com 一、外观与布局 1. 通常由两个摇杆、多个功能按钮、一个显示屏和天线组成。 2. 摇杆一般位于遥控器的中央位置&#xff0c;用于控…

谷歌新作:Unbounded开放世界RPG,AI定义无限游戏新纪元

在开放世界和角色扮演游戏的领域里&#xff0c;玩家们总是渴望着那种无拘无束的自由体验。他们梦想着一个没有空气墙阻隔&#xff0c;没有剧情杀限制&#xff0c;没有任何交互限制的游戏世界。现在&#xff0c;这个梦想可能即将成真。谷歌联合北卡罗来纳大学教堂山分校推出的Un…

Qt文件目录操作

文件目录操作相关类 Qt 为文件和目录操作提供了一些类&#xff0c;利用这些类可以方便地实现一些操作。Qt 提供的与文件和目录操作相关的类包括以下几个&#xff1a; QCoreApplication&#xff1a;用于提取应用程序路径&#xff0c;程序名等文件信息&#xff1b;QFile&#x…

网页web无插件播放器EasyPlayer.js H.265流媒体播放器的decoder.js报Unexpected token ‘<‘错误

EasyPlayer.js H.265流媒体播放器属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff1b;支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#xff…

渗透测试之信息收集 DNS主机发现探测方式NetBIOS 协议发现主机 以及相关PorCheck scanline工具的使用哟

目录 主机发现 利用NetBIOS 协议发现主机 利用TCP/UDP发现主机 PorCheck scanline 利用DNS协议发现主机 主机发现 信息收集中的一项重要工作是发现内网中的主机、数据库、IP段网络设备、安全设备等资产&#xff0c;以便于更快地获取更多权限和密码&#xff0c;更加接近红…

Nginx SSL+tomcat,使用request.getScheme() 取到https协议

架构上使用了 Nginx tomcat 集群, 且nginx下配置了SSL,tomcat no SSL,项目使用https和http协议。 发现 request.getScheme() //总是 http&#xff0c;而不是实际的http或https request.isSecure() //总是false&#xff08;因为总是http&#xff09; request.getRemoteAddr(…

[Redis] Redis服务集群

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

期权懂|上证50ETF期权的交易时间是什么时候?

期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 上证50ETF期权的交易时间是什么时候&#xff1f; 一、开盘集合竞价时间‌&#xff1a; 上午9:15至9:25。在这段时间内&#xff0c;投资者可以提交或撤销委托&#xff0c;但不会立…

FPGA 第7讲 简单组合逻辑译码器

时间&#xff1a;2024.11.15 一、学习内容 1.译码器 译码是编码的逆过程&#xff0c;在编码时&#xff0c;每一种二进制代码&#xff0c;都赋予了特定的含义&#xff0c;即都表示了一个确定的信号或者对象。把代码状态的特定含义翻译出来的过程叫做译码&#xff0c;实现译码操…

jmeter常用配置元件介绍总结之断言

系列文章目录 安装jmeter jmeter常用配置元件介绍总结之断言 9.断言9.1.响应断言9.2.JSON断言9.3.大小断言9.4.JSON JMESPath Assertion9.5.断言持续时间9.6.MD5Hex断言9.7.XPath断言9.8.XPath2 Assertion 9.断言 检查测试中得到的响应数据结果是否符合预期 9.1.响应断言 功…

莱特币转型MEME币:背后隐含的加密市场现象

随着加密市场的风云变幻&#xff0c;莱特币&#xff08;LTC&#xff09;这款曾经的“老牌矿币”近日以自嘲式推文宣布“自己是一个MEME币”&#xff0c;迅速引发了市场的广泛关注和一波围绕MEME币的炒作浪潮。这一举动看似玩笑&#xff0c;却反映出当前加密市场的一种微妙转变&…

【网页设计】CSS3 进阶(动画篇)

1. CSS3 2D 转换 转换&#xff08;transform&#xff09;是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 转换&#xff08;transform&#xff09;你可以简单理解为变形 移动&#xff1a;translate旋转&#xff1a;rotate缩放&#xf…

系统架构设计师:软件架构的演化和维护

软件架构一般会经历初始设计、实际使用、修改完善和退化弃用的过程&#xff0c;其中修改完善的过程实际上就是软件架构的演化和维护过程&#xff0c;演化和维护的目的就是为了使软件能够适应环境的变化而进行的纠错性修改和完善性修改等。 软件架构的演化和维护过程是一个不断…

如何在 Ubuntu 上安装 Jupyter Notebook

本篇文章将教你在 Ubuntu 服务器上安装 Jupyter Notebook&#xff0c;并使用 Nginx 和 SSL 证书进行安全配置。 我将带你一步步在云服务器上搭建 Jupyter Notebook 服务器。Jupyter Notebook 在数据科学和机器学习领域被广泛用于交互式编码、可视化和实验。在远程服务器上运行…

IoT [remote electricity meter]

IoT [remote electricity meter] 物联网&#xff0c;远程抄表&#xff0c;电表数据&#xff0c;举个例子