英文:
Double array $lookup call preserving original structure
问题
我尝试在聚合中填充一个双重数组对象,所以我正在使用`$lookup`函数。集合看起来像这样:
{
foo: [
{
bar: [
{
_id: ObjectId('63f508eedd2962118c37ea36')
}
]
}
]
}
我的lookup如下:
{
$lookup: {
from: "collection",
localField: "foo.bar",
foreignField: "_id",
as: "foo.bar",
},
}
这导致了以下结果:
{
foo: {
bar: [
{
_id: ObjectId('63f508eedd2962118c37ea36'),
field1: "helloworld"
}
]
}
}
而我实际想要的是:
{
foo: [
{
bar: [
{
_id: ObjectId('63f508eedd2962118c37ea36'),
field1: "helloworld"
}
]
}
]
}
有没有关于如何在聚合中实现我想要的效果的想法?
<details>
<summary>英文:</summary>
I'm trying to populate a double array object but in an aggregate so I am utilizing the `$lookup` function. The collection looks something like this:
```BSON
{
foo: [
{
bar: [
{
_id: ObjectId('63f508eedd2962118c37ea36')
}
]
}
]
}
My lookup looks like:
{
$lookup: {
from: "collection",
localField: "foo.bar",
foreignField: "_id",
as: "foo.bar",
},
}
which results in
{
foo: {
bar: [
{
_id: ObjectId('63f508eedd2962118c37ea36'),
field1: "helloworld"
}
]
}
}
where what I actually want is
{
foo: [
{
bar: [
{
_id: ObjectId('63f508eedd2962118c37ea36'),
field1: "helloworld"
}
]
}
]
}
Any ideas on how to achieve what I want in an aggregate?
答案1
得分: 1
-
$lookup
- 使用$lookup
来连接collection
集合并返回bars
数组字段。 -
$set
- 设置foo
数组。2.1.
$map
- 遍历foo
数组中的元素。2.1.1.
$mergeObjects
- 将当前迭代的foo
元素与2.1.1.1.1的结果合并。2.1.1.1. 包含结果为2.1.1.1.1.1的
bar
字段的文档。2.1.1.1.1.
$map
- 遍历bar
数组中的元素。2.1.1.1.1.1.
$mergeObjects
- 将当前迭代的bar
元素与2.1.1.1.1.1.1的结果合并。2.1.1.1.1.1.1.
$first
- 从bars
数组中按_id
匹配获取第一个元素。 -
$unset
- 移除bars
数组。
英文:
Seems a direct map with $lookup
for the nested array is not possible.
-
$lookup
- Join thecollection
collection and return thebars
array field. -
$set
- Setfoo
array.2.1.
$map
- Iterate element infoo
array.2.1.1.
$mergeObjects
- Merge current iteratedfoo
element with the result of 2.1.1.1.2.1.1.1. A document with a
bar
field which contains the result of 2.1.1.1.1.2.1.1.1.1.
$map
- Iterate element inbar
array.2.1.1.1.1.1.
$mergeObjects
- Merge the current iteratedbar
element with the result of 2.1.1.1.1.1.1.2.1.1.1.1.1.1.
$first
- Get the first matching element from thebars
array by_id
s. -
$unset
- Removebars
array.
db.from.aggregate([
{
$lookup: {
from: "collection",
localField: "foo.bar._id",
foreignField: "_id",
as: "bars"
}
},
{
$set: {
foo: {
$map: {
input: "$foo",
as: "foo",
in: {
$mergeObjects: [
"$$foo",
{
bar: {
$map: {
input: "$$foo.bar",
as: "bar",
in: {
$mergeObjects: [
"$$bar",
{
$first: {
$filter: {
input: "$bars",
cond: {
$eq: [
"$$bar._id",
"$$this._id"
]
}
}
}
}
]
}
}
}
}
]
}
}
}
}
},
{
$unset: "bars"
}
])
答案2
得分: 1
也许在 foo
层级上首先使用 $unwind
,然后执行 $lookup
和 $group
会更简单?
db.from.aggregate([
{
"$unwind": "$foo"
},
{
$lookup: {
from: "collection",
localField: "foo.bar._id",
foreignField: "_id",
as: "foo.bar"
}
},
{
$group: {
_id: "$_id",
foo: {
$push: "$foo"
}
}
}
])
英文:
Maybe it would be simpler to $unwind
at foo
level first, do the $lookup
and $group
back the result?
db.from.aggregate([
{
"$unwind": "$foo"
},
{
$lookup: {
from: "collection",
localField: "foo.bar._id",
foreignField: "_id",
as: "foo.bar"
}
},
{
$group: {
_id: "$_id",
foo: {
$push: "$foo"
}
}
}
])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论