在聚合中展平MongoDB嵌套数组
我有这样的文件:在聚合中展平MongoDB嵌套数组,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我有这样的文件: { "many" : {}, "other" : {}, "fields" : {}, "phases" : [ { "type" : 10, "states" : [ { "type" : 10, "time" : ISODate("2018-04-25T13:06:
{
"many" : {},
"other" : {},
"fields" : {},
"phases" : [
{
"type" : 10,
"states" : [
{
"type" : 10,
"time" : ISODate("2018-04-25T13:06:42.990+02:00")
},
{
"type" : 20,
"time" : ISODate("2018-04-25T13:26:12.122+02:00")
},
{
"type" : 30,
"time" : ISODate("2018-04-25T13:26:30.124+02:00")
}
]
},
{
"type" : 20,
"states" : [
{
"type" : 10,
"time" : ISODate("2018-04-25T13:27:58.201+02:00")
}
]
}
]
}
在聚合中,我试图将状态
展平,包括父级的类型
,如下所示(所需输出):
我已经完成了附加的状态
字段,没有使用此聚合的阶段
字段:
db.docs.aggregate([
{
$addFields: {
states: {
$reduce: {
input: "$phases",
initialValue: [],
in: { $concatArrays: ["$$value", "$$this.states"] }
}
}
}
}
])
“许多其他字段”应该保留,因此我认为分组不是一种选择。MongoDB版本是3.4
我尝试了很多事情,但都没有结果。我想知道这是否以及如何可能。您需要使用循环遍历每个数组,然后使用循环遍历到最终的数组
db.state.aggregate(
// Pipeline
[
// Stage 1
{
$unwind: {
path : "$phases",
includeArrayIndex : "arrayIndex", // optional
preserveNullAndEmptyArrays : false // optional
}
},
// Stage 2
{
$unwind: {
path : "$phases.states",
includeArrayIndex : "arrayIndex", // optional
preserveNullAndEmptyArrays : false // optional
}
},
// Stage 3
{
$project: {
"phases":"$phases.type",
"type":"$phases.states.type",
"time":"$phases.states.time",
}
},
// Stage 4
{
$group: {
"_id":"$_id",
states: { $push: { phases: "$phases", type: "$type",time: "$time" } }
}
},
]);
db.collection.aggregate([
{ "$addFields": {
"states": { "$reduce": {
"input": { "$map": {
"input": "$phases",
"as": "pa",
"in": { "$map": {
"input": "$$pa.states",
"as": "st",
"in": { "type": "$$st.type", "time": "$$st.time", "phase": "$$pa.type" }
}}
}},
"initialValue": [],
"in": { "$concatArrays": ["$$value", "$$this"] }
}}
}}
])
Mohit Kumar Bordia的代码看起来很棒。此外,如果还希望返回旧对象(基于Mohit代码):
您可以使用下面的聚合。用于格式化状态数组以包含相位字段
db.docs.aggregate([
{"$addFields":{
"states":{
"$reduce":{
"input":"$phases",
"initialValue":[],
"in":{
"$concatArrays":[
"$$value",
{"$map":{
"input":"$$this.states",
"as":"state",
"in":{"phase":"$$this.type","type":"$$state.type","time":"$$state.time"}
}}
]
}
}
}
}}
])
db.getCollection('flatten').aggregate(
// Pipeline
[
// Stage 1
{
$unwind: {
path : "$phases",
includeArrayIndex : "arrayIndex", // optional
preserveNullAndEmptyArrays : false // optional
}
},
// Stage 2
{
$unwind: {
path : "$phases.states",
includeArrayIndex : "arrayIndex", // optional
preserveNullAndEmptyArrays : false // optional
}
},
// Stage 3
{
$project: {
"_id" : "$_id",
"many" : "$many",
"other" :"$other",
"fields" : "$fields",
"phases":"$phases.type",
"type":"$phases.states.type",
"time":"$phases.states.time",
}
},
// Stage 4
{
$group: {
"_id":"$_id",
many : { $first: "$many"},
other: { "$first": "$other" },
fields: { "$first": "$fields" },
states: { $push: { phases: "$phases", type: "$type",time: "$time" } }
}
},
]);
db.docs.aggregate([
{"$addFields":{
"states":{
"$reduce":{
"input":"$phases",
"initialValue":[],
"in":{
"$concatArrays":[
"$$value",
{"$map":{
"input":"$$this.states",
"as":"state",
"in":{"phase":"$$this.type","type":"$$state.type","time":"$$state.time"}
}}
]
}
}
}
}}
])