Mongoose:如果值存在于对象数组中的数组中,则过滤数据
Posted
技术标签:
【中文标题】Mongoose:如果值存在于对象数组中的数组中,则过滤数据【英文标题】:Mongoose: filter data if value exists in array within array of objects 【发布时间】:2020-11-19 22:00:33 【问题描述】:我有一个使用 Aggregate 的工作 mongoose 查询,我根据对象数组中的值过滤数据,但由于需求变化而遇到麻烦。
这是我的数据在 MongoDB 中的样子(它已经填充了虚拟数据)
"_id" : ObjectId("5ef44528af5a1a2a641cd52b"),
"active" : true,
"name" : "CompanyA",
"contacts" : [
"secondary_emails" : [],
"_id" : ObjectId("5f19727495f4da29403923e3"),
"email" : "contact@gmail.com",
"designation" : "VP Cloud & Security",
"address" : "",
"name" : "Ron"
],
"services" : [
"active" : true,
"_id" : ObjectId("5ef44528af5a1a2a641cd52d"),
"name" : "Company Management",
"title" : "Company Helpline",
"description" : "Offering voice, meetings, collaboration and contact center all on one cloud platform.",
"categories" : [
"SD-WAN",
"Security and Compliance"
],
"sub_categories" : [
"Solution"
],
,
"active" : true,
"_id" : ObjectId("5ef44528af5a1a2a641cd52c"),
"name" : "Company HR",
"title" : "Human Resources",
"description" : "Offering HR Services to all",
"categories" : [
"HR", "Company"
],
"sub_categories" : [
"Solution"
],
]
目标:根据用户提供的类别(假设其“SD-WAN”)过滤服务,之前类别是单数,现在是一组值,因为一个服务可以属于多个类别
以前的解决方案 我用于奇异类别值的猫鼬查询如下:
db.Collection("suppliers").aggregate([
$project:
services:
$filter:
input: "$services",
as: "services",
cond: $eq: ["$$services.category", "SD-WAN" ] ,
,
,
,
,
$match: services: $exists: true, $not: $size: 0 ,
]);
我在尝试在 $$services.categories
中搜索 SD-WAN
时遇到问题,这是一个值数组。有没有办法更新上述查询以使用 $eq
管道运算符或其他解决方案搜索 services.categories
数组中的值。
预期结果
"_id" : ObjectId("5ef44528af5a1a2a641cd52b"),
"services" : [
"active" : true,
"_id" : ObjectId("5ef44528af5a1a2a641cd52d"),
"name" : "Company Management",
"title" : "Company Helpline",
"description" : "Offering voice, meetings, collaboration and contact center all on one cloud platform.",
"categories" : [
"SD-WAN",
"Security and Compliance"
],
"sub_categories" : [
"Solution"
],
]
如果有人能帮助我解决这个问题,我将不胜感激。如果需要更多信息,请询问。谢谢。
【问题讨论】:
【参考方案1】:这就是你要找的东西。
[
$unwind: "$services"
,
$match:
"services.categories": "SD-WAN"
,
$group:
_id: "$_id",
active:
$first: "$active"
,
name:
$first: "$name"
,
contacts:
$first: "$contacts"
,
services:
$addToSet: "$services"
]
-
使用
$unwind
来展平数组
使用$match
进行过滤
使用$group
将其分组。
我们仅扁平化服务。这就是为什么我使用$addToSet
工作Mongo playground
【讨论】:
感谢您的快速回复,完美解决了我的问题! $first 做什么? 当我们展开时,可能会出现数组(“服务”)大小的重复项。所以当我们对它进行分组时,我们只需要第一个对象,因为其他对象是重复的docs.mongodb.com/manual/reference/operator/aggregation/first【参考方案2】:这是另一种不使用聚合的方法 游乐场链接:https://mongoplayground.net/p/jmLghGBXb7f
db.collection.find(
"services":
$elemMatch:
categories:
$regex: "SD-WAN",
$options: "i"
,
"services":
$elemMatch:
categories:
$regex: "SD-WAN",
$options: "i"
)
输出:
[
"_id": ObjectId("5ef44528af5a1a2a641cd52b"),
"services": [
"_id": ObjectId("5ef44528af5a1a2a641cd52d"),
"active": true,
"categories": [
"SD-WAN",
"Security and Compliance"
],
"description": "Offering voice, meetings, collaboration and contact center all on one cloud platform.",
"name": "Company Management",
"sub_categories": [
"Solution"
],
"title": "Company Helpline"
]
]
【讨论】:
这个查询部分起作用,因为它只会返回它找到的第一个类别为SD-WAN
的服务,同一类别可以有多个服务。查询应过滤具有该类别的服务。有没有办法使用 find 来做到这一点?以上是关于Mongoose:如果值存在于对象数组中的数组中,则过滤数据的主要内容,如果未能解决你的问题,请参考以下文章