mongodb - MongoDB:如果属性存在,则获取数组的最后一个元素
问题描述
我想将最后一个设置与现有值聚合。
我的数据结构:
{
_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: [{}]
tosettings.values: {}
将是解决方案的关键。然后我可以project
使用单个值$reverseArray
来$arrayElemAt: [$array, 0]
获取最后一个元素。
解决方案
您可以利用$mergeObjects运算符,因为正如文档所述:
mergeObjects 在合并文档时会覆盖字段值。如果要合并的文档包含相同的字段名称,则结果文档中的字段具有为该字段合并的最后一个文档的值。
由于您有嵌套数组,因此您需要使用 double $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
}
}
])
推荐阅读
- django - 如何在 http 栏中显示类别?
- reactjs - 我在以下 react-redux 代码中遇到初始化错误
- python - 在大多数情况下,VADER polar_scores 将输出返回为“中性”
- json - 如何使用 django rest 框架修改多对多集合
- r - r 数据中彼此相距两倍以内的样本百分比
- c# - 处理 DateTime 以便使用 ASP.NET 仅显示没有时间的日期
- react-native - 反应 60.0 及更高版本的反应本机 Fabric 自动链接错误
- java - 包含视图上的Android onClick()不会让绑定
- javascript - React-native 和 redux 操作
- r - 重新排序表循环中的行