我有一个与以下类似的文件的现有收藏集
{
"_id" : UUID("ef2f3778-c74a-4a40-9169-a7798bc6c776"),
"feedId" : UUID("677d0a5a-0ceb-43d9-954d-bfefddc22ca2"),
"events" : {
"1500" : {
"t" : ISODate("2020-08-20T02:25:00.000Z"),
"a" : {
"Manager" : "Joe",
"Amount" : 20.3
}
},
"1800" : {
"t" : ISODate("2020-08-20T02:30:00.000Z"),
"a" : {
"Manager" : "Joe",
"Amount" : 21.3
}
},
"2100" : {
"t" : ISODate("2020-08-20T02:35:00.000Z"),
"a" : {
"Manager" : "Joe",
"Amount" : 22.3
}
},
"2400" : {
"t" : ISODate("2020-08-20T02:40:00.000Z"),
"a" : {
"Manager" : "Joe",
"Amount" : 23.3
}
}
}
}
我对返回按时间顺序排列的所有“金额”字段值(“ t”字段)的查询感兴趣。现在,我认识到“事件”嵌入文档的结构不太可能正确构建。它应该是一个数组。但这恐怕是徒手的,即没有选择更改文档的选项。如何从集合中具有相同feedId的所有对象中返回类似于[20.3、21.3、22.3、23.3等]的查询?
编辑:我将添加事件对象/文档在每个集合对象上没有统一的名称。即在这里您将看到1500、1800、2100等。但是下一个文档可能只有1500和3000。
参考另一个有相同问题但似乎碰壁的帖子(未将文档架构更改为数组):
答案 0 :(得分:1)
尝试此查询并检查是否符合您的预期要求(例如here)
请注意,我已更改日期以方便阅读。
db.collection.aggregate([
{
"$match": {
"feedId": 2
}
},
{
"$project": {
"events": {
"$objectToArray": "$events"
}
}
},
{
"$unwind": "$events"
},
{
"$sort": {
"events.v.t": 1
}
},
{
"$group": {
"_id": "$_id",
"events": {
"$push": "$events"
}
}
},
{
"$addFields": {
"count": "$events.v.a.Amount"
}
},
{
"$project": {
"count": 1,
"_id": 0
}
}
])
首先$match
个feedId
字段,然后必须使用$objectToArray
,因为您的架构由键值对象组成。
然后$unwind
可以执行$sort
并再次重新组合。
之后,我添加了一个新字段count
,其中包含总额,并且我使用$project
仅保留了该字段。
答案 1 :(得分:1)
@ J.F的回答使我接近。这是对我有用的查询:
db.collection.aggregate(
[
{ $match: { feedId: 2 } },
{ $project: { events: {$objectToArray: "$events"} } },
{
"$unwind": "$events"
},
{
"$sort": {
"events.v.t": 1
}
},
{ $group: { "_id": null, Amounts: { $push: "$events.v.a.Amount" } } },
{
"$project": {
"Amounts": 1,
"_id": 0
}
}
]
)
正在为我产生预期的结果。我希望它是正确的。
结果:
/* 1 */
{
"Amounts" : [
20.3,
21.3,
22.3,
23.3,
24.3,
25.3,
26.3,
27.3,
28.3,
29.3,
30.3,
31.3,
32.3,
33.3,
34.3,
35.3,
36.3,
...