【发布时间】:2018-09-05 10:58:34
【问题描述】:
在我查询的 MongoDB 集合中,每个文档都代表特定时间某个包裹的一些数据。每次收到包裹的更新时,某些字段可能会更新(非空值),而另一些字段则不会(空值)。
为了说明,考虑这个例子。我们收到了 3 个包裹的数据集:
/* 1 */
{
"parcelNum" : "CC123456789FR",
"datetime" : ISODate("2018-09-05T10:48:38.584Z"),
"field1" : "value1_1",
"field2" : "value2_1"
}
/* 2 */
{
"parcelNum" : "CC123456789FR",
"datetime" : ISODate("2018-09-05T10:48:40.566Z"),
"field1" : "value1_2",
"field2" : null
}
/* 3 */
{
"parcelNum" : "CC123456789FR",
"datetime" : ISODate("2018-09-05T10:48:42.777Z"),
"field1" : null,
"field2" : "value2_2"
}
如何为所有字段提取最新的非空值,同时考虑它们所属文档的时间戳?
使用前面的例子,这是我试图得到的:
{
"parcelNum" : "CC123456789FR",
"field1" : "value1_2",
"field2" : "value2_2"
}
我尝试过这种查询,但我找不到如何混合来自多个文档的字段值:
db.testDB.aggregate([
{$sort: { datetime: -1 }},
{$group: { _id: "$parcelNum",
field1: {$first: "$field1" },
field2: {$first: "$field2" }
}}
])
给我:
{
"_id" : "CC123456789FR",
"field1" : null,
"field2" : "value2_2"
}
这是错误的,因为它只使用最新文档中的值,而不是混合所有文档。
我尝试了 Rishi 在另一个主题中提出的另一种方法。他建议不要为每个修订创建一个新文档,而是将修订子文档推送到一个数组中,并在父文档中维护最新修订。
类似这样的:
{
parcelNum: CC123456789FR,
lastUpdated: ISODate("2018-09-05T10:48:42.777Z")
field1: "value1_2",
field2: "value2_2",
revisions: [
{
datetime: ISODate("2018-09-05T10:48:38.584Z"),
field1: "value1_1",
field2: "value2_1"
},
{
datetime: ISODate("2018-09-05T10:48:40.566Z"),
field1: "value1_2",
field2: null
},
{
datetime: ISODate("2018-09-05T10:48:42.777Z"),
field1: null,
field2: "value2_2"
}
]
}
但是,维护最新版本并不那么容易,因为更新不是按时间顺序接收的,然后我可以收到一个“新”文档,它具有较旧的“日期时间”字段值,然后我不能更新这些字段,除非他们是空的。然后,如果我愿意,我必须记录所有字段的最后更新时间戳!
【问题讨论】:
-
"如果我想这样做,我必须记录所有字段的最后更新时间戳!" - 所以?每个时间戳为 32/64 位。我还要补充一点,您最好混合使用而不是一个文档——一个集合用于合并文档,另一个集合用于所有文档。
-
@AgostonHorvath:这只是为了收集可读性的问题,而不是磁盘空间的问题。
标签: mongodb