我再次遇到mongoDB查询。 它必须简单,但我找不到......
假设我有一个像这样的集合/文档:
{
_id: ObjectId("588055a656f0dc1c9327eaf9"),
type: "house",
timeline: [
{
action: "abc",
date: 2017-01-01,
},
{
action: "xyz",
date: 2016-12-12,
}
]
}
我只想查询类型为house
的文档以及之前的操作xyz
- 让我们说 - 2015
...怎么做?
显然,我知道如何通过type
...
db.collection().find({ 'type': 'house' }).toArray()
我也知道如何使用dot.notation
db.collection().find({ 'timeline.action': 'xyz' }).toArray()
但是如何构建一个前面有xyz
行动的查询 - 让我们说 - 2015
?
非常感谢你。
答案 0 :(得分:1)
您可以使用$elemMatch
运算符匹配嵌入字段。 (在评论中错过了那个操作员)
db.collection.find({'timeline': {$elemMatch:{action: 'xyz', 'date':{$lt: "2015-01-01"}}}})
更多https://docs.mongodb.com/manual/reference/operator/query/elemMatch/#array-of-embedded-documents
答案 1 :(得分:1)
使用$ match查找类型条件,使用$ redact获取匹配的'timeline'对象,
db.collection.aggregate([{$match:{type:"house"}},{
$redact: {
"$cond": [{
$and: [{
"$eq": [{
"$ifNull": ["$action", "xyz"]
},
"xyz"
]
}, {
"$lte": [{
"$ifNull": ["$date", ISODate("2015-01-01T00:00:02.015Z")]
},
ISODate("2015-01-01T00:00:02.015Z")
]
}]
}, "$$DESCEND", "$$PRUNE"]
}
}]).pretty()
答案 2 :(得分:0)
由于mongo保存数据的方式,你必须小心这种匹配。
如果您查询
{
action: 'xyz',
date: {$lt: '2015-01-01'}
}
但您的对象保存为
{
date: {$lt: '2015-01-01'},
action: 'xyz'
}
然后由于保存数据的底层结构,mongo将不匹配。
如果你需要匹配多个元素,建议使用$ elemMatch。
{timeline : {
$elemMatch: {
action: 'xyz',
date: {$lt: '2015-01-01'}
}
}}
因为它将匹配每个元素,而不是整个对象。
您的总查询应该类似于
{
type: 'house'
timeline : {
$elemMatch: {
action: 'xyz',
date: {$lt: '2015-01-01'}
}
}
}