mongodb 更新聚合管道中的 Arrayfilter 等价物
Arrayfilter equivalent in mongodb update aggregation pipeline
我有以下数据结构:
[
{
"_id": {
"$oid": "6295d353fccb2f44c3868f9a"
},
"name": "test",
"managerid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"teachers": [],
"employees": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"firstname": "jean",
"lastname": "charles",
"tag": 4595,
"status": 1
}
],
"groups": [
{
"groupid": {
"$oid": "6295fa2191ae50ba47e9d25c"
},
"groupname": "mongroupe",
"employees": [],
"permissions": []
},
{
"groupid": {
"$oid": "6295fa2191ae50ba47e9d25d"
},
"groupname": "mygroup",
"employees": [],
"permissions": []
}
]
}
]
我想将员工对象添加到一个组中。 objective 是为了达到这样的目的:
[
{
"_id": {
"$oid": "6295d353fccb2f44c3868f9a"
},
"name": "test",
"managerid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"teachers": [],
"employees": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"firstname": "jean",
"lastname": "charles",
"tag": 4595,
"status": 1
}
],
"groups": [
{
"groupid": {
"$oid": "6295fa2191ae50ba47e9d25c"
},
"groupname": "mongroupe",
"employees": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"firstname": "jean",
"lastname": "charles"
}
],
"permissions": []
},
{
"groupid": {
"$oid": "6295fa2191ae50ba47e9d25d"
},
"groupname": "mygroup",
"employees": [],
"permissions": []
}
]
}
]
这样员工也被嵌入到组对象中。使用以下代码(基于此答案)这将非常容易:
db.collection.update({
"_id": {
"$oid": "6295d353fccb2f44c3868f9a",
},
"groups.groupid": {
"$oid": "6295fa2191ae50ba47e9d25c"
}
},
{
"$set": {
"groups.$.employees": {
"$concatArrays": [
"$groups.employees",
{
"$filter": {
"input": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
}
}
],
"cond": {
"$not": {
"$in": [
"$$this.employeeid",
"$groups.$.employees.employeeid"
]
}
}
}
}
]
}
}
})
但问题是聚合管道不能与位置运算符一起工作field.$.otherfield
,也不能与数组过滤器一起工作。
因此我无法 select 正确的组("groups.groupid": {"$oid": "6295fa2191ae50ba47e9d25c"}
过滤器)
有人知道该怎么办吗?我对聚合管道还很陌生……这是相关的操场:https://mongoplayground.net/p/8Kgftb2oBpV
您可以使用聚合管道执行以下操作:
$match
符合您的标准
$unwind
在 groups
级别
$addFields
并使用 $filter
处理逻辑
$group
改造展开的结果
$merge
执行更新回集合
db.collection.aggregate([
{
$match: {
"_id": {
"$oid": "6295d353fccb2f44c3868f9a"
},
"groups.groupid": {
"$oid": "6295fa2191ae50ba47e9d25c"
}
}
},
{
"$unwind": {
path: "$groups",
preserveNullAndEmptyArrays: true
}
},
{
"$addFields": {
"groups.employees": {
"$cond": {
"if": {
$eq: [
"$groups.groupid",
ObjectId("6295fa2191ae50ba47e9d25c")
]
},
"then": {
"$reduce": {
"input": "$groups.employees",
"initialValue": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
}
}
],
"in": {
"$cond": {
"if": {
"$in": [
"$$this.employeeid",
"$$value.employeeid"
]
},
"then": "$$value",
"else": {
"$concatArrays": [
"$$value",
[
"$$this"
]
]
}
}
}
}
},
"else": "$groups.employees"
}
}
}
},
{
$group: {
_id: "$_id",
employees: {
$first: "$employees"
},
groups: {
$push: "$groups"
},
"managerid": {
$first: "$managerid"
},
"name": {
$first: "$name"
},
"teachers": {
$first: "$teachers"
}
}
},
{
"$merge": {
"into": "collection",
"on": "_id",
"whenMatched": "replace"
}
}
])
这里是Mongo Playground供您参考。
我有以下数据结构:
[
{
"_id": {
"$oid": "6295d353fccb2f44c3868f9a"
},
"name": "test",
"managerid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"teachers": [],
"employees": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"firstname": "jean",
"lastname": "charles",
"tag": 4595,
"status": 1
}
],
"groups": [
{
"groupid": {
"$oid": "6295fa2191ae50ba47e9d25c"
},
"groupname": "mongroupe",
"employees": [],
"permissions": []
},
{
"groupid": {
"$oid": "6295fa2191ae50ba47e9d25d"
},
"groupname": "mygroup",
"employees": [],
"permissions": []
}
]
}
]
我想将员工对象添加到一个组中。 objective 是为了达到这样的目的:
[
{
"_id": {
"$oid": "6295d353fccb2f44c3868f9a"
},
"name": "test",
"managerid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"teachers": [],
"employees": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"firstname": "jean",
"lastname": "charles",
"tag": 4595,
"status": 1
}
],
"groups": [
{
"groupid": {
"$oid": "6295fa2191ae50ba47e9d25c"
},
"groupname": "mongroupe",
"employees": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
},
"firstname": "jean",
"lastname": "charles"
}
],
"permissions": []
},
{
"groupid": {
"$oid": "6295fa2191ae50ba47e9d25d"
},
"groupname": "mygroup",
"employees": [],
"permissions": []
}
]
}
]
这样员工也被嵌入到组对象中。使用以下代码(基于此答案)这将非常容易:
db.collection.update({
"_id": {
"$oid": "6295d353fccb2f44c3868f9a",
},
"groups.groupid": {
"$oid": "6295fa2191ae50ba47e9d25c"
}
},
{
"$set": {
"groups.$.employees": {
"$concatArrays": [
"$groups.employees",
{
"$filter": {
"input": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
}
}
],
"cond": {
"$not": {
"$in": [
"$$this.employeeid",
"$groups.$.employees.employeeid"
]
}
}
}
}
]
}
}
})
但问题是聚合管道不能与位置运算符一起工作field.$.otherfield
,也不能与数组过滤器一起工作。
因此我无法 select 正确的组("groups.groupid": {"$oid": "6295fa2191ae50ba47e9d25c"}
过滤器)
有人知道该怎么办吗?我对聚合管道还很陌生……这是相关的操场:https://mongoplayground.net/p/8Kgftb2oBpV
您可以使用聚合管道执行以下操作:
$match
符合您的标准$unwind
在groups
级别$addFields
并使用$filter
处理逻辑
$group
改造展开的结果$merge
执行更新回集合
db.collection.aggregate([
{
$match: {
"_id": {
"$oid": "6295d353fccb2f44c3868f9a"
},
"groups.groupid": {
"$oid": "6295fa2191ae50ba47e9d25c"
}
}
},
{
"$unwind": {
path: "$groups",
preserveNullAndEmptyArrays: true
}
},
{
"$addFields": {
"groups.employees": {
"$cond": {
"if": {
$eq: [
"$groups.groupid",
ObjectId("6295fa2191ae50ba47e9d25c")
]
},
"then": {
"$reduce": {
"input": "$groups.employees",
"initialValue": [
{
"employeeid": {
"$oid": "6295d353fccb2f44c3868f99"
}
}
],
"in": {
"$cond": {
"if": {
"$in": [
"$$this.employeeid",
"$$value.employeeid"
]
},
"then": "$$value",
"else": {
"$concatArrays": [
"$$value",
[
"$$this"
]
]
}
}
}
}
},
"else": "$groups.employees"
}
}
}
},
{
$group: {
_id: "$_id",
employees: {
$first: "$employees"
},
groups: {
$push: "$groups"
},
"managerid": {
$first: "$managerid"
},
"name": {
$first: "$name"
},
"teachers": {
$first: "$teachers"
}
}
},
{
"$merge": {
"into": "collection",
"on": "_id",
"whenMatched": "replace"
}
}
])
这里是Mongo Playground供您参考。