【发布时间】:2020-08-17 16:24:00
【问题描述】:
我是 MongoDB 新手,我正在尝试过滤数组中的数组值。下面是模式的一个示例。该模式基本上是一个 3 层字典的转储,其中一个简单的标量对象作为叶节点。
“I”成员包含带有字符串键(k)的键值对的文档数组(外部数组),值(v)是键值对的文档数组(中间数组)以日期作为键和值是另一个字典,它不是这个问题的一部分。
基本上,我需要做的是从中间数组(日期,键值)中检索外部数组(字符串,键值)的给定值的最新数据。
(Collection Sample)
{
"_id" : ObjectId("5eacfbe62758834aefdec003"),
"UserId" : UUID("46942978-29f4-4521-9932-840cead6743e"),
"Data" : {
"I" : [
{
"k" : "LRI39",
"v" : [
{
"k" : ISODate("2020-03-11T20:24:41.591Z"),
"v" : [
{
"k" : ISODate("2020-03-11T20:24:41.594Z"),
"v" : {
"Source" : 1,
"Value" : 19
}
}
]
},
{
"k" : ISODate("2020-01-22T11:37:23.393Z"),
"v" : [
{
"k" : ISODate("2020-01-22T11:37:23.412Z"),
"v" : {
"Source" : 1,
"Value" : 20
}
}
]
}
]
},
...
]
}
}
我已经能够生成一个文档,该文档基本上是您从“数据”到样本末尾看到的内容,是 LRI39 的整个记录,使用:
db.threetier.aggregate([
{
$project: {
"Data.I": {
$filter: {
input: "$Data.I",
as: "item",
cond: {
$eq: [ "$$item.k", "LRI39" ]
}
}
}
}
}
])
但是,无论我做什么,我似乎都无法返回中间数组记录的任何子集:我得到了 2020-03-11 和 2020-01-22 元素,或者我什么也得不到。
我尝试在上面的投影中添加如下所示的阶段,我认为我会得到 1 条记录(2020-01-22 记录),但我都得到了。如果我将日期更改为 2019 年,我将一无所获(如预期的那样)。
$project: {
"Data.I.v": {
$filter: {
input: "$Data.I.v",
as: "stamp",
cond: { $lt: [ "$$stamp.k", ISODate("2020-02-14T00:00:00Z") ] }
}
}
}
我也试过了:
{ $match: { $expr: { $lt: [ "Data.I.v.k", ISODate("2020-02-14T00:00:00Z") ] } } }
但这根本不返回任何结果(可能是因为 $match 适用于文档而不是数组)以及尝试在匹配之前使用 $unwind: "$Data.I.v" 展开数组,但这也不会返回任何结果。
似乎我在这里遗漏了一些基本的东西。我确实意识到 Mongo 被设计为(我认为)将这些数组项作为文档,但我确实想看看这是否会按原样工作。
【问题讨论】:
标签: arrays mongodb aggregation