如何编写以下MongoDB查询
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何编写以下MongoDB查询相关的知识,希望对你有一定的参考价值。
假设我有以下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
道具,但使用timestamp
项目中的type: "foo"
?
如果没有type
等于foo
的子文档,则整个文档被过滤掉,如果有多个子文档type
等于foo
那么它可以匹配任何人。
答案
您可以尝试以下聚合:
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
阶段过滤掉。
以上是关于如何编写以下MongoDB查询的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Symfony 中为使用 queryBuilder 构建的 MongoDB 查询编写单元测试
如何使用 mongoDB 条件查询在 java 中获得更干净的代码 [重复]