Dot*_*arp 5 mongodb mongodb-query aggregation-framework
我认为这可能与这个问题有点类似:如何在嵌入式数组文档中使用图形查找聚合,但始终没有答案,我也没有发表评论以查看作者是否找到解决方案的声誉。
尽管该集合将包含成千上万的文档,但是在查询时我只会被其中的1个约束。当前的目的是使用一个初始$match
阶段,该阶段将产生一个文档。
样本文件
{
attrA: 'foo',
attrB: 'bar',
versions: [
{
status: "live",
things: [
{
key: "thing_1",
parent: null
slug: "thing-1-slug"
},
{
key: "thing_2",
parent: "thing-1-slug",
slug: "thing-2-slug"
},
{
key: "thing_3",
parent: "thing-2-slug",
slug: "thing-3-slug"
},
{
key: "thing_4",
parent: null,
slug: "thing-4-slug"
},
{
key: "thing_5",
parent: "thing-2-slug",
slug: "thing-5-slug"
},
{
key: "thing_6",
parent: "thing-4-slug",
slug: "thing-6-slug"
},
{
key: "thing_7",
parent: null,
slug: "thing-7-slug"
}
]
},
{
status: "draft"
things: [] // same structure and content of things above
}
]
}
Run Code Online (Sandbox Code Playgroud)
注意事项:
我已经尝试过各种聚合查询,但运气还不足。很乐意张贴其中的一些内容(如果有帮助的话),但没有一个接近预期的结果。
我只在查询时关心集合中的单个文档(目的是$match
作为第一阶段)
目前,我无法控制原始属性或文档结构。
我真的想这样做,而不不必使用之类的东西$project
,因为我不知道所有的原始文档的属性提前(attrA
和attrB
示例)。我的想法是,可以通过类似的运营商来做到这一点,$addField
但我不确定所有阶段的模样如何。
我只关心versions
具有的数组元素status === "live"
。如果有一种覆盖方法,versions
在查询结果中仅包含“实时”元素,那就更好了。
key
特定“事物”元素的属性将是一个已知值(基于HTTP请求有效负载),并且应该/可以用作关系/层次结构事物的“起点”。
parent
每个事物元素的属性要么指向另一个事物数组元素的slug
属性,要么为null
多个things
元素可能具有相同的parent
潜在深度没有限制
预期成果:
知道我想“开始”在thing
与,例如key === "thing_3"
,我怎么可以创建一个查询,将重新映射/过滤器things
是“事元素”是一个数组:
things
数组中代表项目的层次结构/关系的所有元素,其中key === "thing_3"
versions
数组限制为具有status === "live"
并已things
根据#1重写其数组的单个元素所需查询结果的示例:
请注意,没有things
元素带有key
thing_4,thing_6和thing_7,因为它们与things
从以下位置开始的元素没有父级/关联性key === "thing_3"
如果它简化了操作,则具有key === "thing_5"
(也具有parent === "thing-2-slug"
)的元素可以包含在结果中,但理想情况下不包括在内。
{
attrA: 'foo',
attrB: 'bar',
versions: [
{
things: [
{
key: "thing_1",
parent: null
slug: "thing-1-slug"
},
{
key: "thing_2",
parent: "thing-1-slug",
slug: "thing-2-slug"
},
{
key: "thing_3",
parent: "thing-2-slug",
slug: "thing-3-slug"
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
添加这么多阶段后,我发现了结果,尽管它的格式不合适,因此您可以自定义或也可以优化:
db.collection.aggregate([
{
$unwind: "$versions"
},
{
$project: {
_id:1,
attrA:1,
attrB:1,
versions: {
$filter: {
input: "$versions.things",
as: "th",
cond: {
$or: [
{ $ne: [ "$$th.parent", null ] },
{
$and: [
{ $eq: [ "$$th.parent", null ] },
{ $eq: [ "$$th.key", "thing_1" ] }
]
}
]
}
}
}
}
},
{
$unwind: "$versions"
},
{
$graphLookup: {
from: "slug",
startWith: "$versions.slug",
connectFromField: "versions.slug",
connectToField: "versions.things.parent",
as: "reportingHierarchy"
}
},
{
$match: {
$expr: { $ne: [ {$size: "$reportingHierarchy" },0 ] }
}
},
{
$group: {
_id: null,
parents: { $addToSet: "$versions.slug" },
data: { $push: "$$ROOT"}
}
},
{
$unwind: "$data"
},
{
$addFields: {
newVersions:
{
$map:
{
input: "$data.reportingHierarchy",
as: "hierarchy",
in: {
"columns": {
$map:
{
input: "$$hierarchy.versions",
as: "version",
in: {
"$filter": {
"input": "$$version.things",
"as": "th",
"cond": {
$or: [
{ $setIsSubset: [ ["$$th.parent"], "$parents" ] },
{ $eq: [ "$$th.key", 'thing_1']}
]
}
}
}
}
}
}
}
}
}
},
{
$project: {
newVersions:1
}
}
])
Run Code Online (Sandbox Code Playgroud)
该查询的结果响应如下:
/* 1 */
{
"_id" : null,
"newVersions" : [
{
"columns" : [
[
{
"key" : "thing_1",
"parent" : null,
"slug" : "thing-1-slug"
},
{
"key" : "thing_2",
"parent" : "thing-1-slug",
"slug" : "thing-2-slug"
},
{
"key" : "thing_3",
"parent" : "thing-2-slug",
"slug" : "thing-3-slug"
},
{
"key" : "thing_5",
"parent" : "thing-2-slug",
"slug" : "thing-5-slug"
}
],
[
{
"key" : "thing_1",
"parent" : null,
"slug" : "thing-1-slug"
},
{
"key" : "thing_2",
"parent" : "thing-1-slug",
"slug" : "thing-2-slug"
},
{
"key" : "thing_3",
"parent" : "thing-2-slug",
"slug" : "thing-3-slug"
},
{
"key" : "thing_5",
"parent" : "thing-2-slug",
"slug" : "thing-5-slug"
}
]
]
}
]
},
/* 2 */
{
"_id" : null,
"newVersions" : [
{
"columns" : [
[
{
"key" : "thing_1",
"parent" : null,
"slug" : "thing-1-slug"
},
{
"key" : "thing_2",
"parent" : "thing-1-slug",
"slug" : "thing-2-slug"
},
{
"key" : "thing_3",
"parent" : "thing-2-slug",
"slug" : "thing-3-slug"
},
{
"key" : "thing_5",
"parent" : "thing-2-slug",
"slug" : "thing-5-slug"
}
],
[
{
"key" : "thing_1",
"parent" : null,
"slug" : "thing-1-slug"
},
{
"key" : "thing_2",
"parent" : "thing-1-slug",
"slug" : "thing-2-slug"
},
{
"key" : "thing_3",
"parent" : "thing-2-slug",
"slug" : "thing-3-slug"
},
{
"key" : "thing_5",
"parent" : "thing-2-slug",
"slug" : "thing-5-slug"
}
]
]
}
]
},
/* 3 */
{
"_id" : null,
"newVersions" : [
{
"columns" : [
[
{
"key" : "thing_1",
"parent" : null,
"slug" : "thing-1-slug"
},
{
"key" : "thing_2",
"parent" : "thing-1-slug",
"slug" : "thing-2-slug"
},
{
"key" : "thing_3",
"parent" : "thing-2-slug",
"slug" : "thing-3-slug"
},
{
"key" : "thing_5",
"parent" : "thing-2-slug",
"slug" : "thing-5-slug"
}
],
[
{
"key" : "thing_1",
"parent" : null,
"slug" : "thing-1-slug"
},
{
"key" : "thing_2",
"parent" : "thing-1-slug",
"slug" : "thing-2-slug"
},
{
"key" : "thing_3",
"parent" : "thing-2-slug",
"slug" : "thing-3-slug"
},
{
"key" : "thing_5",
"parent" : "thing-2-slug",
"slug" : "thing-5-slug"
}
]
]
}
]
},
/* 4 */
{
"_id" : null,
"newVersions" : [
{
"columns" : [
[
{
"key" : "thing_1",
"parent" : null,
"slug" : "thing-1-slug"
},
{
"key" : "thing_2",
"parent" : "thing-1-slug",
"slug" : "thing-2-slug"
},
{
"key" : "thing_3",
"parent" : "thing-2-slug",
"slug" : "thing-3-slug"
},
{
"key" : "thing_5",
"parent" : "thing-2-slug",
"slug" : "thing-5-slug"
}
],
[
{
"key" : "thing_1",
"parent" : null,
"slug" : "thing-1-slug"
},
{
"key" : "thing_2",
"parent" : "thing-1-slug",
"slug" : "thing-2-slug"
},
{
"key" : "thing_3",
"parent" : "thing-2-slug",
"slug" : "thing-3-slug"
},
{
"key" : "thing_5",
"parent" : "thing-2-slug",
"slug" : "thing-5-slug"
}
]
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
结果是逆风,因此有多个条目,但您可以自定义它。
注意:根据“thing_1”的值,您将根据您的要求获得层次结构数据。
归档时间: |
|
查看次数: |
102 次 |
最近记录: |