数组表达式运算符判断数组中是否包含元素( i n ) 并获取元素索引 ( in)并获取元素索引( in)并获取元素索引(indexOfArray)
一、初始化成员数据
plain
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:代表的是数组
例子:判断成员是否喜欢苹果
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"favoriteApple": {
$in: [ "apple", "$fruits" ]
}
}
}
])
聚合查询的结果如下:
plain
{
"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断言数组操作改进聚合查询:
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"favoriteApple": {
$cond: {
if: { $isArray: "$fruits" },
then: { $in: [ "apple", "$fruits" ] },
else: false
}
}
}
}
])
聚合查询的结果如下:
plain
{ "_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的索引
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"indexApple": {
$indexOfArray: [ "$fruits", "apple" ]
}
}
}
])
聚合查询的结果如下:
plain
{ "_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)
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"indexApple": {
$indexOfArray: [ "$fruits", "apple", 0 ,1 ]
}
}
}
])
聚合查询的结果如下:
bash
{ "_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个元素
二、准备工作
初始化成员数据
bash
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:找到每个人最喜欢吃的前两个水果
bash
db.persons.aggregate([
{
$project: {
"name": 1,
"favoriteFruits": { $slice: [ "$fruits", 2 ] }
}
}
])
聚合查询的结果如下:
bash
{ "_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:找到每个人最喜欢吃的最后两个水果
bash
db.persons.aggregate([
{
$project: {
"name": 1,
"favoriteFruits": { $slice: [ "$fruits", -2 ] }
}
}
])
聚合查询的结果如下:
bash
{ "_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:找到每个人最喜欢吃的第二个水果
bash
db.persons.aggregate([
{
$project: {
"name": 1,
"favoriteFruits": { $slice: [ "$fruits", 1, 1 ] }
}
}
])
聚合查询的结果如下:
bash
{ "_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为负数,会如何处理
bash
db.persons.aggregate([
{
$project: {
"name": 1,
"favoriteFruits": { $slice: [ "$fruits", -2, 1 ] }
}
}
])
聚合查询的结果如下:
bash
{ "_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,会如何处理
bash
db.persons.aggregate([
{
$project: {
"name": 1,
"favoriteFruits": { $slice: [ "$fruits", -10, 1 ] }
}
}
])
聚合查询的结果如下:
bash
{ "_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)
数组表达式运算符主要用于文档中数组的操作,本篇我们主要介绍数组表达式运算符中用于过滤数组的操作,下面我们进行详细介绍:
一、语法
bash
{
$filter:
{
input: <array>,
cond: <expression>,
as: <string>,
limit: <number expression>
}
}
其中,
input:代表的是数组
cond:代表的是条件
as:可选,定义的变量,用于接收数组中的当前元素,如果未定义在cond表达式中可以使用$$this获取数组中的当前元素
limit:可选,限制数组中元素的个数
二、准备工作
初始化零食数据
bash
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的型号信息
bash
db.goods.aggregate([
{
$project: {
types: {
$filter: {
input: "$types",
cond: { $eq: [ "$$this.size", "L" ] }
}
}
}
}
])
等效于:
bash
db.goods.aggregate([
{
$project: {
types: {
$filter: {
input: "$types",
as: "type",
cond: { $eq: [ "$$type.size", "L" ] }
}
}
}
}
])
聚合查询的结果如下:
bash
{ "_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元的型号进行查询
bash
db.goods.aggregate([
{
$project: {
types: {
$filter: {
input: "$types",
as: "type",
cond: { $gt: [ "$$type.price", 5 ] }
}
}
}
}
])
聚合查询的结果如下:
bash
{ "_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" : [ ] }
多个查询条件
bash
cond: {
$and: [
{ $gte: ['$$item.timestamp_start', fromTimestamp] },
{ $lt: ['$$item.timestamp_start', toTimestamp] }
]
}
数组表达式运算符( a r r a y E l e m A t , arrayElemAt, arrayElemAt,first,$last)
数组表达式运算符主要用于文档中数组的操作,本篇我们主要介绍数组表达式运算符中用于获取数组元素的操作,下面我们进行详细介绍:
一、准备工作
初始化成员数据
plain
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:找到每个人最喜欢吃的第一个水果
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"firstFruit": { $arrayElemAt: [ "$fruits", 0 ] }
}
}
])
聚合查询的结果如下:
plain
{ "_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:找到每个人最喜欢吃的最后一个水果
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"lastFruit": { $arrayElemAt: [ "$fruits", -1 ] }
}
}
])
聚合查询的结果如下:
plain
{ "_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: }
获取数组中第一个元素
例子:找到每个人最喜欢吃的第一个水果
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"firstFruit": { $first: "$fruits" }
}
}
])
等效于:
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"firstFruit": { $arrayElemAt: [ "$fruits", 0 ] }
}
}
])
聚合查询的结果如下:
plain
{ "_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: }
获取数组中最后一个元素
例子:找到每个人最喜欢吃的最后一个水果
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"lastFruit": { $last: "$fruits" }
}
}
])
等效于:
plain
db.persons.aggregate([
{
$project: {
"name": 1,
"lastFruit": { $arrayElemAt: [ "$fruits", -1 ] }
}
}
])
聚合查询的结果如下:
plain
{ "_id" : "1001", "name" : "张三", "lastFruit" : "orange" }
{ "_id" : "1002", "name" : "李四", "lastFruit" : "apple" }
{ "_id" : "1003", "name" : "王五", "lastFruit" : "orange" }
{ "_id" : "1004", "name" : "赵六" }
{ "_id" : "1005", "name" : "田七", "lastFruit" : null }