让我们考虑我有三个伪集合,如下面的
用户:
{ "_id" : ObjectId("5a2a2c3dcf7961800e44dfc9"), "uid" : 1234,
"name" : "ashish", "email" : "info@gmail.com" },
{ "_id" : ObjectId("5a2a2c51cf7961800e44dfca"), "uid" : 1235,
"name" : "swapnil", "email" : "info@femail.com" }
bank_details :
{ "_id" : ObjectId("5a2a2c9bcf7961800e44dfcb"), "uid" : 1234, "acc_no" : 1111 },
{ "_id" : ObjectId("5a2a2cc9cf7961800e44dfcc"), "uid" : 1234, "acc_no" : 2222 },
{ "_id" : ObjectId("5a2a2cd7cf7961800e44dfcd"), "uid" : 1235, "acc_no" : 3333 },
{ "_id" : ObjectId("5a2a2cdccf7961800e44dfce"), "uid" : 1235, "acc_no" : 4444 }
银行
{ "_id" : ObjectId("5a2a2d05cf7961800e44dfcf"), "acc_no" : 1111, "balance" : 100 },
{ "_id" : ObjectId("5a2a2d10cf7961800e44dfd0"), "acc_no" : 2222, "balance" : 200 },
{ "_id" : ObjectId("5a2a2d19cf7961800e44dfd1"), "acc_no" : 3333, "balance" : 300 },
{ "_id" : ObjectId("5a2a2d21cf7961800e44dfd2"), "acc_no" : 4444, "balance" : 400 }
我希望输出如下
{ "_id" : ObjectId("5a2a2c3dcf7961800e44dfc9"), "uid" : "1234",
"name" : "ashish", "email" : "info@gmail.com" ,
bank_details: [{
acc_no:'1111',
balance:'100'
},{
acc_no:'2222',
balance:'200'
}]}
对于每个用户个人资料,我确信可以使用$lookup
和$group
运算符完成此操作,但我无法实现,我尝试使用多种方式执行此操作。任何人都可以为所需结果编写一个示例查询。
我正在尝试使用NodeJs中的mongoose编写查询
答案 0 :(得分:1)
您可以使用两次查找和分组来完成此操作。查看以下查询:
db.getCollection('users').aggregate([{
$lookup:
{
from: "bank_details",
localField: "uid",
foreignField: "uid",
as: "bank_details"
}
},
{ $unwind:{ path: "$bank_details", preserveNullAndEmptyArrays: true }},
{
$lookup:{
from: "bank",
localField: "bank_details.acc_no",
foreignField: "acc_no",
as: "banks"
}
},
{ $unwind: { path: "$banks", preserveNullAndEmptyArrays: true } },
{
$group: {
_id: "$_id",
uid: {$first: "$uid"},
name: {$first: "$name"},
email: {$first: "$email"},
bank_details: {$push: {acc_no: "$banks.acc_no", balance: "$banks.balance"}}
}
},
{
"$project": {
uid: 1,
name: 1,
email: 1,
bank_details: { "$setDifference": [ "$bank_details", [{}, null] ] }
}
}
])
结果:
/* 1 */
{
"_id" : ObjectId("5a2a2c51cf7961800e44dfca"),
"uid" : 1235.0,
"name" : "swapnil",
"email" : "info@femail.com",
"bank_details" : [
{
"acc_no" : 3333.0,
"balance" : 300.0
},
{
"acc_no" : 4444.0,
"balance" : 400.0
}
]
}
/* 2 */
{
"_id" : ObjectId("5a2a2c3dcf7961800e44dfc9"),
"uid" : 1234.0,
"name" : "ashish",
"email" : "info@gmail.com",
"bank_details" : [
{
"acc_no" : 1111.0,
"balance" : 100.0
},
{
"acc_no" : 2222.0,
"balance" : 200.0
}
]
}
答案 1 :(得分:0)
如果您不想丢失没有bank_details
的用户,则必须在放松之前添加$project
。通过" $放松"你展平bank_details
数组和具有空数组的文档,因为没有任何东西可以解开,所以会消失。因此,您可以检查bank_detail
数组是否为空并向字段添加零值:
db.getCollection('users').aggregate([{
$lookup: {
from: "bank_details",
localField: "uid",
foreignField: "uid",
as: "bank_details"
}
},
{
$project: {
"_id": "$_id",
uid: "$uid",
name: "$name",
email: "$email",
bank_details: {
$cond: [{
$eq: ["$bank_details", []]
},
[{
_id: 0,
uid: {
$literal: NumberInt(0)
},
acc_no: {
$literal: NumberInt(0)
}
}], '$bank_details'
]
}
}
},
{
$unwind: "$bank_details"
},
{
$lookup: {
from: "bank",
localField: "bank_details.acc_no",
foreignField: "acc_no",
as: "banks"
}
},
{
$project: {
"_id": "$_id",
uid: "$uid",
name: "$name",
email: "$email",
bank_details: "$bank_details",
banks: {
$cond: [{
$eq: ["$banks", []]
},
[{
_id: 0,
acc_no: {
$literal: NumberInt(0)
},
balance: {
$literal: NumberInt(0)
}
}], '$banks'
]
}
}
},
{
$unwind: "$banks"
},
{
$group: {
"_id": "$_id",
uid: {
$first: "$uid"
},
name: {
$first: "$name"
},
email: {
$first: "$email"
},
bank_details: {
$push: {
acc_no: "$banks.acc_no",
balance: "$banks.balance"
}
}
}
}
])
此处是查询结果:
/* 1 */
{
"_id" : ObjectId("5a2a83a53b3899dec93be178"),
"uid" : 1239,
"name" : "emil",
"email" : "emil@femail.com",
"bank_details" : [
{
"acc_no" : 0.0,
"balance" : 0.0
}
]
}
/* 2 */
{
"_id" : ObjectId("5a2a2c51cf7961800e44dfca"),
"uid" : 1235,
"name" : "swapnil",
"email" : "info@femail.com",
"bank_details" : [
{
"acc_no" : 3333,
"balance" : 300
},
{
"acc_no" : 4444,
"balance" : 400
}
]
}
/* 3 */
{
"_id" : ObjectId("5a2a2c3dcf7961800e44dfc9"),
"uid" : 1234,
"name" : "ashish",
"email" : "info@gmail.com",
"bank_details" : [
{
"acc_no" : 1111,
"balance" : 100
},
{
"acc_no" : 2222,
"balance" : 200
}
]
}