大家好,
我需要一些帮助来让聚合管道工作,我已经尝试了一段时间,但只做了一半。这是我的设置
用户文档如下:
{
"_id": { "$oid": "5fea4f976ca46d93c010d33d" },
.....................
"firstname": "firstname1",
"lastname": "lastname1",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
..................
"certifications": {
certs: [
{
"_id": "5fea44b96ca46d93c010d330",
"itemID": 1,
"date_certified": "2011-05-30 05:09:48"
},
{
"_id": "5fea44b96ca46d93c010d334",
"itemID": 3,
"date_certified": "2007-01-30 06:01:51"
},
{
"_id": "5fea44b96ca46d93c010d337",
"itemID": 5,
"date_certified": "2007-09-21 16:52:52"
}
]
},
.......................
...................
.....................
},
{
"_id": { "$oid": "5fea4f976ca46d93c010545453" },
.....................
.....................
"firstname": "firstname2",
"lastname": "lastname2",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
..................
"certifications": {
certs: [
{
"_id": "5fea44b96ca46d93c010d330",
"itemID": 2,
"date_certified": "2011-05-30 05:09:48"
},
{
"_id": "5fea44b96ca46d93c010d334",
"itemID": 4,
"date_certified": "2007-01-30 06:01:51"
}
]
},
.......................
...................
.....................
}
认证文档是后续
[{
"_id": {
"$oid": "5fea44b96ca46d93c010d32e"
},
"itemID": 1,
"acronym": "acro1",
"country": "my Great Country",
"name": {
"key1": "My Key 1 description",
"key2": "My Key 2 description",
"key3": "My Key 3 description",
"key4": "My Key 4 description"
},
"website": "www.myGreatWebsite.com"
},
{
"_id": {
"$oid": "5fea44b96ca46d93c010d32f"
},
"itemID": 2,
"acronym": "acro2",
"country": "my Great Country",
"name": {
"key1": "My Key 1 description",
"key2": "My Key 2 description",
"key3": "My Key 3 description",
"key4": "My Key 4 description"
},
"website": "www.myGreatWebsite.com"
},
{
"_id": {
"$oid": "5fea44b96ca46d93c010d330"
},
"itemID": 3,
"country": "my Great Country",
"name": {
"key1": "My Key 1 description",
"key2": "My Key 2 description",
"key3": "My Key 3 description",
"key4": "My Key 4 description"
},
"website": "www.myGreatWebsite.com"
},
{
"_id": {
"$oid": "5fea44b96ca46d93c010d331"
},
"itemID": 4,
"country": "my Great Country",
"name": {
"key1": "My Key 1 description",
"key2": "My Key 2 description",
"key3": "My Key 3 description",
"key4": "My Key 4 description"
},
"website": "www.myGreatWebsite.com"
},
{
"_id": {
"$oid": "5fea44b96ca46d93c010d332"
},
"itemID": 5,
"country": "my Great Country",
"name": {
"key1": "My Key 1 description",
"key2": "My Key 2 description",
"key3": "My Key 3 description",
"key4": "My Key 4 description"
},
"website": "www.myGreatWebsite.com"
}]
现在我的聚合
db.users.aggregate([
{
'$lookup': {
'from': 'certifications',
'let': {
'certs': '$certifications.certs'
},
'pipeline': [
{
'$match': {
'$expr': {
'$in': [
'$itemID', '$$certs.itemID'
]
}
}
}, {
'$project': {
'_id': 0,
'itemID': '$itemID',
'description': '$name.key1',
'acronyme': '$acronym',
'country': '$country',
'count': {
'$size': '$$certs'
},
'date_cert': '$$certs.date_certified'
}
}
],
'as': 'certifications'
}
}
])
结果是
{
.........
...........
"firstname": "firstname1",
"lastname": "lastname1",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
..................
certification: {
certs: [
{
itemID: 1,
country: 'my Great Country',
description: 'My Key 1 description',
count: 1,
date_cert: [
0:"2005-01-06 10:48:16"
]
},
]
}
........
.........
},
{
.........
...........
"firstname": "firstname2",
"lastname": "lastname2",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
..................
certification: {
certs: [
{
itemID: 2,
country: 'my Great Country',
description: 'My Key 2 description',
count: 2,
date_cert: [
"2005-01-06 10:48:16"
"2014-06-21 22:44:56"
]
},
{
itemID: 4,
country: 'my Great Country',
description: 'My Key 4 description',
count: 2,
date_cert: [
"2005-01-06 10:48:16"
"2014-06-21 22:44:56"
]
}
]
}
........
.........
}
但是预期的结果是
{
.........
...........
"firstname": "firstname1",
"lastname": "lastname1",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
..................
certification: {
certs: [
{
itemID: 1,
country: 'my Great Country',
description: 'My Key 1 description',
date_cert: "2005-01-06 10:48:16"
},
],
count: 1,
}
........
.........
},
{
.........
...........
"firstname": "firstname2",
"lastname": "lastname2",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
..................
certification: {
certs: [
{
itemID: 2,
country: 'my Great Country',
description: 'My Key 2 description',
date_cert: "2005-01-06 10:48:16"
},
{
itemID: 4,
country: 'my Great Country'
description: 'My Key 4 description',
date_cert: "2014-06-21 22:44:56"
}
],
count: 2
}
........
.........
}
基本上,我希望将管道匹配阶段的结果与证书查找的文档合并,这样我就可以同时使用两者。任何指针在公式化聚合时都将受到极大的赞赏。
谢谢
$unwind
解构certs
数组$lookup
和certifications
通过certifications.certs.itemID
作为localField,itemID
作为foreignField,结果为certification
$unwind
解构来自查找和certification
中的结果$group
通过_id
,重建certs
数组,并使用$mergeObjects
合并后推送您需要的字段,使用$sum
获取计数
db.users.aggregate([
{ $unwind: "$certifications.certs" },
{
$lookup: {
from: "certifications",
localField: "certifications.certs.itemID",
foreignField: "itemID",
as: "certification"
}
},
{ $unwind: "$certification" },
{
$group: {
_id: "$_id",
certs: {
$push: {
$mergeObjects: [
"$certifications.certs",
{
country: "$certification.country",
description: "$certification.name.key1"
}
]
}
},
count: { $sum: 1 }
}
}
])
游乐场
第二种方法没有$unroll和$group,这可能会导致性能和速度问题,
$lookup
和certifications
集合$map
迭代certifications.certs
数组的循环$reduce
迭代certification
的循环、检查itemID
的条件并返回特定字段- 返回到
$map
,使用$mergeObjects
合并当前对象并从$reduce
返回对象 - 使用$size获取
certs
的计数`
db.users.aggregate([
{
$lookup: {
from: "certifications",
localField: "certifications.certs.itemID",
foreignField: "itemID",
as: "certification"
}
},
{
$addFields: {
"certification": "$$REMOVE",
"certifications.certs": {
$map: {
input: "$certifications.certs",
as: "c",
in: {
$mergeObjects: [
"$$c",
{
$reduce: {
input: "$certification",
initialValue: {},
in: {
$cond: [
{ $eq: ["$$this.itemID", "$$c.itemID"] },
{
country: "$$this.country",
description: "$$this.name.key1"
},
"$$value"
]
}
}
}
]
}
}
},
"certifications.count": { $size: "$certifications.certs" }
}
}
])
游乐场