Mongodb 使用聚合框架过滤深层嵌套数组
Mongodb filtering deeply nested arrays with aggregation framework
提前感谢您查看此内容...
我的文档:
{
"_id" : { "$oid" : "550b2873e9dd90068070c31b" },
"dateCreated" : { "$date" : 1426794611867 },
"sections" : [
{
"_id" : { "$oid" : "550b2881e9dd90068070c31d" },
"index" : 0,
"name" : "Section 2",
"slides" : [
{
"_id" : { "$oid" : "550b288ce9dd90068070c321" },
"index" : 0,
"status" : "Unpublished"
},
{
"_id" : { "$oid" : "55105b87e9dd90068033ba4a" },
"index" : 1,
"status" : "Published"
}
]
},
{
"_id" : { "$oid" : "550b287ae9dd90068070c31c" },
"index" : 1,
"name" : "Section 1",
"slides" : [
{
"_id": { "$oid": "550b2888e9dd90068070c31f" },
"index" : 0,
"status": "Unpublished"
},
{
"_id" : { "$oid" : "550b288be9dd90068070c320" },
"index" : 1,
"status" : "Unpublished"
}
]
}
]
}
和期望的结果,我们 return 仅包含至少一张包含所有已发布幻灯片的已发布幻灯片的部分
{
"_id" : { "$oid" : "550b2873e9dd90068070c31b" },
"dateCreated" : { "$date" : 1426794611867 },
"sections" : [
{
"_id" : { "$oid" : "550b2881e9dd90068070c31d" },
"index" : 0,
"name" : "Section 2",
"slides" : [
{
"_id" : { "$oid" : "55105b87e9dd90068033ba4a" },
"index" : 1,
"status" : "Published"
}
]
}
]
}
到目前为止我有这个:
col.aggregate
([
{$match : {'name': name}},
{$unwind:'$sections'},
{$unwind:'$sections.slides'},
{$match:{'$sections.slides.status': "Published"}},
{$group:{_id:'$_id', slides:{$push:'$slides'}}}
])
我很难全神贯注于分组,特别是将每个幻灯片数组嵌套在其父部分数组中。另外,我想省略任何空白部分。
我以前从未使用过聚合方法,但我相信这是正确的方法。 mongo 文档在涉及深度嵌套数组时有点稀疏。
了解 MongoDB 管道的 $redact 阶段。
在第一次迭代中我这样做了:
.aggregate({
$redact: {
$cond: {
if: { $eq: ["$status", "Unpublished"] },
then: "$$PRUNE",
else: "$$DESCEND"
}
}
}, {
$redact: {
$cond: {
if: { $eq: ["$slides", []] },
then: "$$PRUNE",
else: "$$DESCEND"
}
}
})
你可以尝试用更优雅的方式重写它。我很确定有一种方法可以用单个 $redact 阶段来实现它,但是你必须浏览手册并找到合适的操作符。希望它会有所帮助。祝你好运。
提前感谢您查看此内容... 我的文档:
{
"_id" : { "$oid" : "550b2873e9dd90068070c31b" },
"dateCreated" : { "$date" : 1426794611867 },
"sections" : [
{
"_id" : { "$oid" : "550b2881e9dd90068070c31d" },
"index" : 0,
"name" : "Section 2",
"slides" : [
{
"_id" : { "$oid" : "550b288ce9dd90068070c321" },
"index" : 0,
"status" : "Unpublished"
},
{
"_id" : { "$oid" : "55105b87e9dd90068033ba4a" },
"index" : 1,
"status" : "Published"
}
]
},
{
"_id" : { "$oid" : "550b287ae9dd90068070c31c" },
"index" : 1,
"name" : "Section 1",
"slides" : [
{
"_id": { "$oid": "550b2888e9dd90068070c31f" },
"index" : 0,
"status": "Unpublished"
},
{
"_id" : { "$oid" : "550b288be9dd90068070c320" },
"index" : 1,
"status" : "Unpublished"
}
]
}
]
}
和期望的结果,我们 return 仅包含至少一张包含所有已发布幻灯片的已发布幻灯片的部分
{
"_id" : { "$oid" : "550b2873e9dd90068070c31b" },
"dateCreated" : { "$date" : 1426794611867 },
"sections" : [
{
"_id" : { "$oid" : "550b2881e9dd90068070c31d" },
"index" : 0,
"name" : "Section 2",
"slides" : [
{
"_id" : { "$oid" : "55105b87e9dd90068033ba4a" },
"index" : 1,
"status" : "Published"
}
]
}
]
}
到目前为止我有这个:
col.aggregate
([
{$match : {'name': name}},
{$unwind:'$sections'},
{$unwind:'$sections.slides'},
{$match:{'$sections.slides.status': "Published"}},
{$group:{_id:'$_id', slides:{$push:'$slides'}}}
])
我很难全神贯注于分组,特别是将每个幻灯片数组嵌套在其父部分数组中。另外,我想省略任何空白部分。
我以前从未使用过聚合方法,但我相信这是正确的方法。 mongo 文档在涉及深度嵌套数组时有点稀疏。
了解 MongoDB 管道的 $redact 阶段。 在第一次迭代中我这样做了:
.aggregate({
$redact: {
$cond: {
if: { $eq: ["$status", "Unpublished"] },
then: "$$PRUNE",
else: "$$DESCEND"
}
}
}, {
$redact: {
$cond: {
if: { $eq: ["$slides", []] },
then: "$$PRUNE",
else: "$$DESCEND"
}
}
})
你可以尝试用更优雅的方式重写它。我很确定有一种方法可以用单个 $redact 阶段来实现它,但是你必须浏览手册并找到合适的操作符。希望它会有所帮助。祝你好运。