以下是我的示例文档:
{
updated: [
1461062102,
1461062316
],
name: "test1",
etc: "etc"
}
{
updated: [
1460965492,
1461060275
],
name: "test2",
etc: "etc"
}
{
updated: [
1461084505
],
name: "test3",
etc: "etc"
}
{
updated: [
1461060430
],
name: "test4",
etc: "etc"
}
{
updated: [
1460965715,
1461060998
],
name: "test5",
etc: "etc"
}
查找查询的正确用法是在$gte
和$lte
条件中获取与更新日期匹配的所有文档吗?
例如
db.test.find({'updated':{$elemMatch:{$gte:1461013201,$lte:1461099599}}})
我可以使用$或将其设置为updated.0:{$gte:1461013201,$lte:1461099599}
,update.1:{$gte:1461013201,$lte:1461099599}
等,但如果我的数组包含更多更新的日期会怎样?
据我所知,$ elemMatch并不是'符合我的标准,因为它只匹配数组中的第一个出现。
答案 0 :(得分:2)
好问题。您使用$elemMatch
走在了正确的轨道上,但这确实采用了标准运营商未涵盖的其他逻辑。
所以你要么做$redact
:
db.test.aggregate([
{ "$match": {
'updated': { '$elemMatch':{ '$gte':1461013201, '$lte':1461099599 } }
}},
{ "$redact": {
"$cond": {
"if": {
"$allElementsTrue": {
"$map": {
"input": "$updated",
"as": "upd",
"in": {
"$and": [
{ "$gte": [ "$$upd", 1461013201 ] },
{ "$lte": [ "$$upd", 1461099599 ] }
]
}
}
}
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
或者在早于MongoDB 2.6的版本中,使用$where
子句处理:
db.test.find({
'updated': { '$elemMatch':{ '$gte':1461013201, '$lte':1461099599 } },
"$where": function() {
return this.updated.filter(function(el) {
return el >= 1461013201 && el <= 1461099599;
}).length == this.updated.length;
}
})
问题在于,尽管一般的原生“查询”操作符可以告诉您一个数组成员符合条件,但它无法告诉您所有它们都符合条件。
因此,可以使用$map
和$allElementsTrue
来测试条件,这些都可以从MongoDB 2.6获得。使用MongoDB 3.2,$filter
和$size
等同于以下JavaScript测试。
或者您可以使用$where
的JavaScript评估来测试与原始数据相关的“已过滤”数组长度,并看到它们仍然相同。
这是为了让所有与所提供的范围条件相匹配而构建的额外逻辑。聚合方法是本机代码,而不是JavaScript解释。相比之下,它可以更快地运行更多。
但是你仍然希望在所有情况下都保留$elemMatch
。
当然,这里有匹配的文件:
{
"updated" : [
1461062102,
1461062316
],
"name" : "test1",
"etc" : "etc"
}
{
"updated" : [
1461084505
],
"name" : "test3",
"etc" : "etc"
}
{
"updated" : [
1461060430
],
"name" : "test4",
"etc" : "etc"
}