mongodb聚合-将数组的内容设置为输入,同时存储同级键 [英] mongodb aggregation - setting the contents of array as input, while storing sibling keys
问题描述
当我有从上一步传递来的以下数据作为计数所有分支/树/林中的所有叶子"的输入时,我正处于聚合管道的中间.如以下问题所示: 只有当我直接从集合中阅读时,我才能正常工作. 我的问题是-我怎么能 注意-我只是想让(b)为初学者工作,但是我似乎无法对待森林".数组,以便上面链接中的解决方案可以发挥作用. 然后-完成该阶段后,提取(a)中存储的内容,以获取所有计数的原始格式. 这是使用 通过此新 MongoPlayground链接获取测试数据. 检查从链接获取的更新查询: 输出: I'm in the middle of an aggregation pipeline when I have the following data passed from the previous step as input to a "count all leaves in all branches/trees/forests" as indicated in this question: Need guidance on mongo aggregate lookup to count subnodes in all child nodes for each node I have that all working properly, but only if I'm reading directly from a collection. My question is - how can I Note - I tried to get just (b) working for starters, but I can't seem to treat "forests" as an array so that the solution in the link above can do its magic. Then- when that phase is done, extract what was stored in (a) to get the original format back with all the counts. That is the main disadvantage of using Get the test data with those additional fields from this new MongoPlayground link. Check the updated query taken from the link: Output:
这篇关于mongodb聚合-将数组的内容设置为输入,同时存储同级键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
a)保存forest_ranger和some_other_data供以后使用";b)并通过将森林映射为的数组来开始下一阶段输入到计算所有叶子数"的文档?
$ group
的主要缺点.您必须使用 $ first 或 $ last 像这样:>
db.Forests.aggregate([{$ unwind:" $ forests"},{$ unwind:" $ forests.trees"},{$ unwind:"$ forests.trees.branches"},{$ lookup:{来自:叶子",localField:"forests.trees.branches.branch_id",foreignField:"branch_id",如:"forests.trees.branches.leaves";}},{$ addFields:{"forests.trees.branches.leaf_count":{$ size:"$ forests.trees.branches.leaves"}}},{$ project:{" forests.trees.branches.leaves" ;: 0}},{$ group:{_ID: {forest_id:"$ forests.forest_id",tree_id:" $ forests.trees.tree_id"},forest_ranger:{$ first:" $ forest_ranger"},some_other_data:{$ first:" $ some_other_data"},leaf_count:{$ sum:"$ forests.trees.branches.leaf_count"},分支机构:{$ push:" $ forests.trees.branches"}}},{$ group:{_id:"$ _ id.forest_id",forest_ranger:{$ first:" $ forest_ranger"},some_other_data:{$ first:" $ some_other_data"},leaf_count:{$ sum:"$ leaf_count";},树木:{$ push:{leaf_count:{$ sum:"$ leaf_count";},tree_id:"$ _ id.tree_id",分支机构:"$ branches"}}}},{$ group:{_id:null,forest_ranger:{$ first:" $ forest_ranger"},some_other_data:{$ first:" $ some_other_data"},leaf_count:{$ sum:"$ leaf_count";},森林:{$ push:{leaf_count:{$ sum:"$ leaf_count";},forest_id:"$ _ id",树:"$ trees"}}}},{$ project:{_id:0}}])
<代码> {"forest_ranger":"bob"," some_other_data":{数据":虚拟数据";},"leaf_count";:4森林":[{"leaf_count";:3"forest_id":"forestA",树":[{"leaf_count";:1"tree_id":"treeB",分支":[{"branch_id":"branchB","leaf_count";:1}]},{"leaf_count";:2"tree_id":"treeA",分支":[{"branch_id":"branchA","leaf_count";:1},{"branch_id":"branchA1","leaf_count";:1},{"branch_id":"branchA2","leaf_count";:0}]}]},{"leaf_count";:1"forest_id":"forestB",树":[{"leaf_count";:0,"tree_id":"treeD",分支":[{"branch_id":"branchD","leaf_count";:0}]},{"leaf_count";:1"tree_id":"treeC",分支":[{"branch_id":"branchC","leaf_count";:1}]}]},{"leaf_count";:0,"forest_id":"forestC",树":[{"leaf_count";:0,"tree_id":"treeE",分支":[{"branch_id":"branchE","leaf_count";:0}]}]}]}
{
forest_ranger: "bob",
some_other_data: {},
forests: [
{
forest_id: 'forestA',
trees: [
{
tree_id: 'treeA',
branches: [
{
branch_id: 'branchA',
}
]
}
]
}
],
}
a) save forest_ranger and some_other_data "for later"
b) and start the next stage by mapping forests as the array of
documents that are input to the "count all leaves"?
$group
. You have to explicitly carry forward every non participating fields using either $first or $last like this:db.Forests.aggregate([
{ $unwind: "$forests" },
{ $unwind: "$forests.trees" },
{ $unwind: "$forests.trees.branches" },
{
$lookup: {
from: "Leaves",
localField: "forests.trees.branches.branch_id",
foreignField: "branch_id",
as: "forests.trees.branches.leaves"
}
},
{
$addFields: {
"forests.trees.branches.leaf_count": { $size: "$forests.trees.branches.leaves" }
}
},
{
$project: { "forests.trees.branches.leaves": 0 }
},
{
$group: {
_id: {
forest_id: "$forests.forest_id",
tree_id: "$forests.trees.tree_id"
},
forest_ranger: { $first: "$forest_ranger" },
some_other_data: { $first: "$some_other_data" },
leaf_count: { $sum: "$forests.trees.branches.leaf_count" },
branches: { $push: "$forests.trees.branches" }
}
},
{
$group: {
_id: "$_id.forest_id",
forest_ranger: { $first: "$forest_ranger" },
some_other_data: { $first: "$some_other_data" },
leaf_count: { $sum: "$leaf_count" },
trees: {
$push: {
leaf_count: { $sum: "$leaf_count" },
tree_id: "$_id.tree_id",
branches: "$branches"
}
}
}
},
{
$group: {
_id: null,
forest_ranger: { $first: "$forest_ranger" },
some_other_data: { $first: "$some_other_data" },
leaf_count: { $sum: "$leaf_count" },
forests: {
$push: {
leaf_count: { $sum: "$leaf_count" },
forest_id: "$_id",
trees: "$trees"
}
}
}
},
{
$project: { _id: 0 }
}
])
{
"forest_ranger" : "bob",
"some_other_data" : {
"data" : "Dummy data"
},
"leaf_count" : 4,
"forests" : [
{
"leaf_count" : 3,
"forest_id" : "forestA",
"trees" : [
{
"leaf_count" : 1,
"tree_id" : "treeB",
"branches" : [
{
"branch_id" : "branchB",
"leaf_count" : 1
}
]
},
{
"leaf_count" : 2,
"tree_id" : "treeA",
"branches" : [
{
"branch_id" : "branchA",
"leaf_count" : 1
},
{
"branch_id" : "branchA1",
"leaf_count" : 1
},
{
"branch_id" : "branchA2",
"leaf_count" : 0
}
]
}
]
},
{
"leaf_count" : 1,
"forest_id" : "forestB",
"trees" : [
{
"leaf_count" : 0,
"tree_id" : "treeD",
"branches" : [
{
"branch_id" : "branchD",
"leaf_count" : 0
}
]
},
{
"leaf_count" : 1,
"tree_id" : "treeC",
"branches" : [
{
"branch_id" : "branchC",
"leaf_count" : 1
}
]
}
]
},
{
"leaf_count" : 0,
"forest_id" : "forestC",
"trees" : [
{
"leaf_count" : 0,
"tree_id" : "treeE",
"branches" : [
{
"branch_id" : "branchE",
"leaf_count" : 0
}
]
}
]
}
]
}