Mongodb 汇总数组中某个字段的 $lookup
Mongodb aggrregate $lookup of a field inside array
我有一个包含 3 个集合的数据库。
第一个有一些参考其他文件的文件。
我需要查询 填充 项目 上的引用,以便加载需求。
我已经设法 $lookup requirements 数组,但我无法在 optionals 数组上使用它,因为它是数组的对象。请注意,它是一个具有引用和需要保留的额外字段的对象。
db.projects.findOne({user: ObjectId("602acb4b839ec6001d3ef506")})
{
"_id" : ObjectId("6033cf8503ac5003f873cc9b"),
"date" : 1614008193362,
"requirements" : [
ObjectId("6032c1249588930368d7603c"),
ObjectId("6032c2dc9588930368d7603e")
],
"status" : "ACTIVE",
"hours" : 10,
"expire" : 1629560197,
"optionals" : [
{
"requirement" : ObjectId("602e3104dd86db01c89dd47e"),
"amount" : 10
},
{
"requirement" : ObjectId("603171e89588930368d76038"),
"amount" : 10
}
],
"user" : ObjectId("602acb4b839ec6001d3ef506"),
"__v" : 0
}
db.requirements.findOne()
{
"_id" : ObjectId("602da2bbdd86db01c89dd479"),
"date" : "1613602429148",
"status" : "ACTIVE",
"name" : "Test1",
"description" : "Test1 description",
"creator" : ObjectId("602acb4b839ec6001d3ef506"),
"__v" : 0
}
这里指出了一个基于$lookup的解决方案,但我无法让它工作:MongoDB aggregate field in array of objects
db.project.aggregate([
{
$match : {user: ObjectId($interesting_user)}
},
{
$lookup: {
from: "requirements",
localField: "requirements",
foreignField: "_id",
as: "requirements"
}
},
{
$lookup: {
from: "requirements",
localField: "optionals.requirement",
foreignField: "_id",
as: "optionals.requirement"
}
},
]).pretty()
我在这里遗漏了什么?浏览 MongoDb 文档没有给我任何解决方案
思路是$unwind
optionals
既然是数组,就执行$lookup
,然后$group
就可以了。这一切只是为了保留amount
字段!所以试试这个:
注意 我在测试数据的 requirements
集合中只创建了两个字段。您将获得案例中的所有其他剩余字段。
db.project.aggregate([
{
$match : {user: ObjectId("602acb4b839ec6001d3ef506")}
},
{
$lookup: {
from: "requirements",
localField: "requirements",
foreignField: "_id",
as: "requirements"
}
},
{ $unwind: "$optionals" },
{
$lookup: {
from: "requirements",
let: { requirements: "$optionals.requirement" },
pipeline: [
{
$match: {
$expr: {
$eq:["$_id", "$$requirements"]
}
}
}
],
as: "optionals.requirement"
}
},
{ $unwind: "$optionals.requirement" },
{
$group: {
_id: "$_id",
date: { $first: "$date" },
requirements: { $first: "$requirements" },
status: { $first: "$status" },
hours: { $first: "$hours" },
expire: { $first: "$expire" },
optionals: { $push: "$optionals" },
user: { $first: "$user" }
}
}
]);
输出:
{
"_id" : ObjectId("6033cf8503ac5003f873cc9b"),
"date" : 1614008193362,
"requirements" : [
{
"_id" : ObjectId("6032c1249588930368d7603c"),
"name" : "Test1"
},
{
"_id" : ObjectId("6032c2dc9588930368d7603e"),
"name" : "Test2"
}
],
"status" : "ACTIVE",
"hours" : 10,
"expire" : 1629560197,
"optionals" : [
{
"requirement" : {
"_id" : ObjectId("602e3104dd86db01c89dd47e"),
"name" : "Test3"
},
"amount" : 10
},
{
"requirement" : {
"_id" : ObjectId("603171e89588930368d76038"),
"name" : "Test4"
},
"amount" : 10
}
],
"user" : ObjectId("602acb4b839ec6001d3ef506")
}
我有一个包含 3 个集合的数据库。 第一个有一些参考其他文件的文件。
我需要查询 填充 项目 上的引用,以便加载需求。 我已经设法 $lookup requirements 数组,但我无法在 optionals 数组上使用它,因为它是数组的对象。请注意,它是一个具有引用和需要保留的额外字段的对象。
db.projects.findOne({user: ObjectId("602acb4b839ec6001d3ef506")})
{
"_id" : ObjectId("6033cf8503ac5003f873cc9b"),
"date" : 1614008193362,
"requirements" : [
ObjectId("6032c1249588930368d7603c"),
ObjectId("6032c2dc9588930368d7603e")
],
"status" : "ACTIVE",
"hours" : 10,
"expire" : 1629560197,
"optionals" : [
{
"requirement" : ObjectId("602e3104dd86db01c89dd47e"),
"amount" : 10
},
{
"requirement" : ObjectId("603171e89588930368d76038"),
"amount" : 10
}
],
"user" : ObjectId("602acb4b839ec6001d3ef506"),
"__v" : 0
}
db.requirements.findOne()
{
"_id" : ObjectId("602da2bbdd86db01c89dd479"),
"date" : "1613602429148",
"status" : "ACTIVE",
"name" : "Test1",
"description" : "Test1 description",
"creator" : ObjectId("602acb4b839ec6001d3ef506"),
"__v" : 0
}
这里指出了一个基于$lookup的解决方案,但我无法让它工作:MongoDB aggregate field in array of objects
db.project.aggregate([
{
$match : {user: ObjectId($interesting_user)}
},
{
$lookup: {
from: "requirements",
localField: "requirements",
foreignField: "_id",
as: "requirements"
}
},
{
$lookup: {
from: "requirements",
localField: "optionals.requirement",
foreignField: "_id",
as: "optionals.requirement"
}
},
]).pretty()
我在这里遗漏了什么?浏览 MongoDb 文档没有给我任何解决方案
思路是$unwind
optionals
既然是数组,就执行$lookup
,然后$group
就可以了。这一切只是为了保留amount
字段!所以试试这个:
注意 我在测试数据的 requirements
集合中只创建了两个字段。您将获得案例中的所有其他剩余字段。
db.project.aggregate([
{
$match : {user: ObjectId("602acb4b839ec6001d3ef506")}
},
{
$lookup: {
from: "requirements",
localField: "requirements",
foreignField: "_id",
as: "requirements"
}
},
{ $unwind: "$optionals" },
{
$lookup: {
from: "requirements",
let: { requirements: "$optionals.requirement" },
pipeline: [
{
$match: {
$expr: {
$eq:["$_id", "$$requirements"]
}
}
}
],
as: "optionals.requirement"
}
},
{ $unwind: "$optionals.requirement" },
{
$group: {
_id: "$_id",
date: { $first: "$date" },
requirements: { $first: "$requirements" },
status: { $first: "$status" },
hours: { $first: "$hours" },
expire: { $first: "$expire" },
optionals: { $push: "$optionals" },
user: { $first: "$user" }
}
}
]);
输出:
{
"_id" : ObjectId("6033cf8503ac5003f873cc9b"),
"date" : 1614008193362,
"requirements" : [
{
"_id" : ObjectId("6032c1249588930368d7603c"),
"name" : "Test1"
},
{
"_id" : ObjectId("6032c2dc9588930368d7603e"),
"name" : "Test2"
}
],
"status" : "ACTIVE",
"hours" : 10,
"expire" : 1629560197,
"optionals" : [
{
"requirement" : {
"_id" : ObjectId("602e3104dd86db01c89dd47e"),
"name" : "Test3"
},
"amount" : 10
},
{
"requirement" : {
"_id" : ObjectId("603171e89588930368d76038"),
"name" : "Test4"
},
"amount" : 10
}
],
"user" : ObjectId("602acb4b839ec6001d3ef506")
}