> 文章列表 > MongoDB 聚合管道中使用数组表达式运算符判断数组中是否包含元素($in)并获取元素索引($indexOfArray)

MongoDB 聚合管道中使用数组表达式运算符判断数组中是否包含元素($in)并获取元素索引($indexOfArray)

MongoDB 聚合管道中使用数组表达式运算符判断数组中是否包含元素($in)并获取元素索引($indexOfArray)

数组表达式运算符主要用于文档中数组的操作,之前我们介绍了如果获取文档数组中的元素:  MongoDB 聚合管道中使用数组表达式运算符获取数组中指定位置的元素($arrayElemAt,$first,$last)https://blog.csdn.net/m1729339749/article/details/130128708

这篇我们介绍如何使用数组表达式运算符判断数组中是否包含元素并获取元素索引:

一、准备工作

初始化成员数据

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> ] }

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

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字段导致的。

这里我们需要使用$isArray断言数组操作进行聚合查询,如果您对$isArray断言数组操作不太了解,可以参考:
MongoDB 聚合管道中使用数组表达式运算符断言数组($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> ] }

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

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),包含起始位置对应的索引,不包含结束位置对应的索引