我想将最后一个设置与现有值进行汇总。
我的数据结构:
{
_id: 1,
...(many other fields)...
settings: [
{
_id: 11,
values: [
{
likesFruit: true,
likesMeat: true,
}
]
},
{
_id: 12,
values: [
{
likesFruit: false
}
]
}
]
},
{
_id: 2,
...(many other fields)...
settings: [] // empty
}
{
_id: 1,
...(many other fields)...
likesFruit: false,
likesMeat: true
},
{
_id: 2,
...(many other fields)...
}
我需要一个解决方案,该解决方案不会在设置例如空/不包含所有道具。例如_id: 2
不包含任何设置。因此,我不想展开它并对其进行过滤以进行特定设置,因为即使没有设置,我仍然需要根对象。
我尝试过addFields
:
$addFields: {
likesFruit: "$settings.value.likesFruit",
likesMeat: "$settings.value.likesMeat"
}
这让我离开了:
_id: 1,
...(many other fields)...
settings: [...],
likesFruit: [[true], [false]]
likesMeat: [[], [true]]
我尝试过滤以下内容:
$addFields: {
likesFruit: {
$filter: {
input: "$likesMeat",
as: "items",
cond: { $ne : ["$$items", null ] }
}
}
}
我的主要问题是双重嵌套。我感兴趣的“ settings.value”里面只有一个对象。因此,我想从settings.values: [{}]
到settings.values: {}
是解决方案的关键。然后,我可以project
的单个值,使用$reverseArray
和$arrayElemAt: [$array, 0]
来获取最后一个元素。
答案 0 :(得分:1)
由于文档指出,您可以利用$mergeObjects运算符:
mergeObjects在合并文档时会覆盖字段值。如果要合并的文档包含相同的字段名称,则结果文档中的字段具有上次为该字段合并的文档中的值。
由于具有嵌套数组,因此需要双$reduce来聚合数据。您还可以使用$replaceRoot将汇总值提升到最高水平
db.col.aggregate([
{
$addFields: {
settingsAggregated: {
$reduce: {
input: "$settings",
initialValue: {},
in: {
$mergeObjects: [ "$$value",
{ $reduce: { input: "$$this.values", initialValue: {}, in: { $mergeObjects: [ "$$value", "$$this" ] } } }
]
}
}
}
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [ "$$ROOT", "$settingsAggregated" ]
}
}
},
{
$project: {
settings: 0,
settingsAggregated: 0
}
}
])