mongodb - 在匹配阶段后将展开的数组分组并保留父数据/结构
问题描述
有一些问题让我的聚合工作。我有一个$lookup
我加入两个集合的地方,在加入的一个中,我有嵌套数组,其中包含我想要匹配的对象。匹配部分似乎起作用了,因为我没有得到我在$group
舞台上期望的结构之后$unwind
。
这是一个带有示例数据的 mongo 游乐场https://mongoplayground.net/p/rWuX7ziT395
原始加入的文档具有这样的结构,其中我在一些approvalStatus 字段上匹配并且我得到正确的字段。但我也想保留“父”中的字段,即版本、allHaveSigned、isLatestVersion 等。
"agreements": [
{
"_id": {
"$oid": "612c8d394459ebd2483a0920"
},
"agreementVersion": [
{
"version": 1,
"allHaveSigned": false,
"_id": {
"$oid": "612c8d394459ebd2483a0921"
},
"approvalStatus": [
{
"_id": {
"$oid": "612c8d394459ebd2483a0922"
},
"publisherSignsFor": {
"$oid": "60801bef03a9cd5f4a097e76"
},
"signingPerson": {
"$oid": "60d06fc53a7fc65be3787df8"
},
"isSignedByPublisher": true
},
{
"_id": {
"$oid": "612c8d394459ebd2483a0923"
},
"publisherSignsFor": null,
"signingPerson": {
"$oid": "60d06fc53a7fc65be3787df8"
},
"isSignedByPublisher": false
},
{
"_id": {
"$oid": "612c8d394459ebd2483a0921"
},
"publisherSignsFor": {
"$oid": "60801bef03a9cd5f4a097e76"
},
"signingPerson": {
"$oid": "60d06fc53a7fc65be3787df9"
},
"isSignedByPublisher": true
}
],
"isLatestVersion": true,
"createdAt": {
"$date": "2021-08-30T07:48:09.979Z"
}
}
],
这就是我的管道的样子
db.songs.aggregate([
{
"$lookup": {
"from": "agreements",
"localField": "agreements.songComposition",
"foreignField": "_id",
"as": "agreements.songComposition"
}
},
{
"$unwind": {
"path": "$agreements.songComposition",
"preserveNullAndEmptyArrays": false
}
},
{
"$unwind": {
"path": "$agreements.songComposition.agreementVersion",
"preserveNullAndEmptyArrays": false
}
},
{
"$unwind": {
"path": "$agreements.songComposition.agreementVersion.approvalStatus",
"preserveNullAndEmptyArrays": false
}
},
{
"$match": {
"$and": [
{
"agreements.songComposition.agreementVersion.isLatestVersion": true
},
{
"agreements.songComposition.agreementVersion.approvalStatus.signingPerson": ObjectId("60d06fc53a7fc65be3787df8")
}
],
"$or": [
{
"agreements.songComposition.agreementVersion.approvalStatus.isApprovedByUser": false
},
{
"agreements.songComposition.agreementVersion.approvalStatus.isApprovedByUser": {
"$exists": false
}
}
]
}
},
{
"$facet": {
"songs": [
{
"$group": {
"_id": "$_id",
"title": {
"$first": "$title"
},
"artistName": {
"$first": "$artistName"
},
"agreements": {
"$push": "$agreements.songComposition"
},
"count": {
"$sum": 1
}
}
}
],
"countAgreements": [
{
"$group": {
"_id": null,
"count": {
"$sum": 1
}
}
}
]
}
},
{
"$project": {
"songs": 1,
"sumAgreements": {
"$arrayElemAt": [
"$countAgreements.count",
0
]
}
}
}
])
结果看起来像这样,我在agreements
数组中得到了两个元素,它应该只有一个,我认为这是因为我无法approvalStatus
正确加入字段或缺少其他内容。
[
{
"songs": [
{
"_id": ObjectId("60debdaae7593406b682e45d"),
"agreements": [
{
"__v": 0,
"_id": ObjectId("612c8d394459ebd2483a0920"),
"addedAt": ISODate("2021-08-30T07:48:09.979Z"),
"agreementVersion": {
"_id": ObjectId("612c8d394459ebd2483a0921"),
"allHaveSigned": false,
"approvalStatus": {
"_id": ObjectId("612c8d394459ebd2483a0922"),
"isSignedByPublisher": true,
"publisherSignsFor": ObjectId("60801bef03a9cd5f4a097e76"),
"signingPerson": ObjectId("60d06fc53a7fc65be3787df8")
},
"createdAt": ISODate("2021-08-30T07:48:09.979Z"),
"isLatestVersion": true,
"version": 1
}
},
{
"__v": 0,
"_id": ObjectId("612c8d394459ebd2483a0920"),
"addedAt": ISODate("2021-08-30T07:48:09.979Z"),
"agreementVersion": {
"_id": ObjectId("612c8d394459ebd2483a0921"),
"allHaveSigned": false,
"approvalStatus": {
"_id": ObjectId("612c8d394459ebd2483a0923"),
"isSignedByPublisher": false,
"publisherSignsFor": null,
"signingPerson": ObjectId("60d06fc53a7fc65be3787df8")
},
"createdAt": ISODate("2021-08-30T07:48:09.979Z"),
"isLatestVersion": true,
"version": 1
}
}
],
"artistName": "My test artisters",
"count": 2,
"title": "Branches"
}
],
"sumAgreements": 2
}
]
我想要的结果看起来像这样
[
{
"songs": [
{
"_id": ObjectId("60debdaae7593406b682e45d"),
"agreements": [
{
"__v": 0,
"_id": ObjectId("612c8d394459ebd2483a0920"),
"addedAt": ISODate("2021-08-30T07:48:09.979Z"),
"agreementVersion": [
{
"_id": ObjectId("612c8d394459ebd2483a0921"),
"allHaveSigned": false,
"approvalStatus": [
{
"_id": ObjectId("612c8d394459ebd2483a0922"),
"isSignedByPublisher": true,
"publisherSignsFor": ObjectId("60801bef03a9cd5f4a097e76"),
"signingPerson": ObjectId("60d06fc53a7fc65be3787df8")
},
{"_id": ObjectId("612c8d394459ebd2483a0923"),
"isSignedByPublisher": false,
"publisherSignsFor": null,
"signingPerson": ObjectId("60d06fc53a7fc65be3787df8")
},
],
"createdAt": ISODate("2021-08-30T07:48:09.979Z"),
"isLatestVersion": true,
"version": 1
}
]
},
],
"artistName": "My test artisters",
"count": 2,
"title": "Branches"
}
],
"sumAgreements": 2
}
]
感谢您的帮助!
解决方案
您可以$lookup
与管道一起使用,
$lookup
与协议并传递songComposition
为id
$match
id
(健康)状况$unwind
解构agreementVersion
数组$unwind
解构approvalStatus
数组$match
您的approvalStatus
房产条件$group
通过_id
andagreementVersion
,_id
获取必填字段并构造approvalStatus
数组$group
通过_id
并构造agreementVersion
数组$group
通过 null 并构造songs
数组
db.songs.aggregate([
{
"$lookup": {
"from": "agreements",
"let": { "id": "$agreements.songComposition" },
"pipeline": [
{ $match: { $expr: { $eq: ["$$id", "$_id"] } } },
{
$unwind: {
"path": "$agreementVersion",
"preserveNullAndEmptyArrays": false
}
},
{
$unwind: {
"path": "$agreementVersion.approvalStatus",
"preserveNullAndEmptyArrays": false
}
},
{
"$match": {
"$and": [
{ "agreementVersion.isLatestVersion": true },
{ "agreementVersion.approvalStatus.signingPerson": ObjectId("60d06fc53a7fc65be3787df8") },
{
"$or": [
{ "agreementVersion.approvalStatus.isApprovedByUser": false },
{ "agreementVersion.approvalStatus.isApprovedByUser": { "$exists": false } }
]
}
]
}
},
{
$group: {
_id: {
_id: "$_id",
agv_id: "$agreementVersion._id"
},
addedAt: { $first: "$addedAt" },
__v: { $first: "$__v" },
version: { $first: "$agreementVersion.version" },
allHaveSigned: { $first: "$agreementVersion.allHaveSigned" },
isLatestVersion: { $first: "$agreementVersion.isLatestVersion" },
createdAt: { $first: "$agreementVersion.createdAt" },
approvalStatus: { $push: "$agreementVersion.approvalStatus" },
count: { $sum: 1 }
}
},
{
$group: {
_id: "$_id._id",
addedAt: { $first: "$addedAt" },
__v: { $first: "$__v" },
agreementVersion: {
$push: {
_id: "$_id.agv_id",
version: "$version",
allHaveSigned: "$allHaveSigned",
isLatestVersion: "$isLatestVersion",
createdAt: "$createdAt",
approvalStatus: "$approvalStatus",
count: "$count"
}
},
count: { $sum: "$count" }
}
}
],
"as": "agreements"
}
},
{
$group: {
_id: null,
songs: { $push: "$$ROOT" },
count: { $sum: { $sum: "$agreements.count" } }
}
}
])
推荐阅读
- php - 如何使用 htaccess 重写规则修复“服务器找不到请求的页面”错误
- python - 在数组中打印以进行列表理解
- c# - 定义一个 C# 方法,该方法接受任何可与方括号一起使用的对象
- javascript - 如何自定义
- sql-server - 如何压缩查询结果?
- node.js - node js将pdf / docx从服务器转换为客户端的html
- fortran - 通过例程调用在并行区域中使用 PGI 而不是 Cray 进行编译时出现运行时错误
- windows-10 - DDEV http://projectname.ddev.local 在 Windows 10 上不起作用,而 http://127.0.0.1:randomport 确实起作用
- php - mysqli_fetch_assoc() 有没有办法打印空时没有数据?
- python - 如何通过请求将环境变量从 python 脚本传递到 gitlab ci?