假设我有以下foobar
集合:
{
"foobar": [
{
"_id": "abc",
"history": [
{
"type": "foo",
"timestamp": 123456789.0
},
{
"type": "bar",
"timestamp": 123456789.0
}
]
},
{
"_id": "dfg",
"history": [
{
"type": "baz",
"timestamp": 123456789.0
},
{
"type": "bar",
"timestamp": 123456789.0
}
]
},
{
"_id": "hij",
"history": [
{
"type": "foo",
"timestamp": 123456789.0
},
{
"type": "bar",
"timestamp": 123456789.0
},
{
"type": "foo",
"timestamp": 123456789.0
}
]
}
]
}
如何基于$gte
项目中的$lte
属性查询(foobar
/ timestamp
)history
个项目,但使用{{ 1}}从timestamp
吗?
如果没有type: "foo"
等于type
的子文档,则将整个文档过滤掉,如果有多个foo
等于type
的子文档,则它可以匹配任何人。
答案 0 :(得分:1)
您可以尝试以下汇总:
var threshold = 123456788;
db.foobar.aggregate([
{
$addFields: {
foobar: {
$filter: {
input: "$foobar",
as: "doc",
cond: {
$let: {
vars: {
foo: {
$arrayElemAt: [
{
$filter: {
input: "$$doc.history",
as: "history",
cond: {
$eq: [ "$$history.type", "foo" ]
}
}
},
0]
}
},
in: {
$gt: [ "$$foo.timestamp", threshold ]
}
}
}
}
}
}
}
])
$addFields可用于覆盖现有字段(foobar
)。要筛选出不符合您条件的所有子文档,可以使用$filter(外部的子文档)。对于每个foobar
文档,您可以使用$let定义临时变量foo
。您需要内部$filter
来获取所有history
元素,其中type
是foo
,然后需要$arrayElemAt来获取第一个元素。然后,您只需要$gt
或$lt
来进行比较。
对于没有foo
的那些子文档,将返回undefined
,然后在$gt
阶段将其过滤掉。