node.js - 具有 _id 关系的类型的最后一个值
问题描述
我有一个 Event 集合,其中包含一个type
可以是0
、1
、2
、3
、4
和日期5
的事件。createdAt
每个事件都与另一个称为 RTS 的集合相关。
我想为每个 Rts 收集每种类型的最后一个事件。
使用我的解决方案的问题:
问题是,我必须types
一一描述才能使其发挥作用。是否有任何解决方案可以通过type
值诱导动态密钥创建?
这是我现在得到的:
- 我对数据进行排序
- Group by
idRTS
包含指向第二个集合的链接。对于每种类型,将值推送到特定数组中。 - 从类型数组中删除空值。
- 只保留第一个值
(the most updated)
。 - 使数据可呈现。
[
{
$sort: {
idRTS: -1,
createdAt: -1
}
},
{
$group: {
_id: '$idRTS',
type0: {
$push: {
$cond: {
if: {
$eq: [
'$type', 0
]
},
then: '$$ROOT',
else: null
}
}
},
type5: {
$push: {
$cond: {
if: {
$eq: [
'$type', 5
]
},
then: '$$ROOT',
else: null
}
}
}
}
},
{
$project: {
_id: '$_id',
type0: {
'$filter': {
'input': '$type0',
'as': 'd',
'cond': {
'$ne': [
'$$d', null
]
}
}
},
type5: {
$filter: {
input: '$type5',
as: 'd',
cond: {
$ne: [
'$$d', null
]
}
}
}
}
},
{
$project: {
_id: '$_id',
type0: {
$arrayElemAt: [
'$type0', 0
]
},
type5: {
'$arrayElemAt': [
'$type5', 0
]
}
}
}
]
解决方案
$match
输入 0 或 5$sort
按降序idRTS
排列createdAt
$group
通过两者idRTS
和createdAt
字段并获取第一个对象,这将获得两种类型的第一个文档$group
byidRTS
和 make 两种类型的数组,采用 k(key) 和 v(value) 格式$project
使用将type
数组转换为对象$objectToArray
db.collection.aggregate([
{ $match: { type: { $in: [0, 5] } } },
{
$sort: {
idRTS: -1,
createdAt: -1
}
},
{
$group: {
_id: {
idRTS: "$idRTS",
type: "$type"
},
type: { $first: "$$ROOT" }
}
},
{
$group: {
_id: "$_id.idRTS",
type: {
$push: {
k: { $toString: "$type.type" },
v: "$type"
}
}
}
},
{ $project: { type: { $arrayToObject: "$type" } } }
])