获取日期范围内的数组元素 [英] Get elements of an array in date range
问题描述
这是我的MongoDB集合中的示例文档:
This is an example document in my MongoDB collection:
var user: [{
"_id" : ObjectId("5391b11a3c0a9ac01300006d"),
"injurydata" : {
"injuryinformation" : [
{
"status" : "current",
"updateddate" : ISODate("2014-06-06T12:16:20.306Z"),
"updatedby" : "",
"dateofinjury" : ISODate("2014-06-27T18:30:00.000Z"),
"_id" : ObjectId("5391b11a3c0a9ac01300006f")
}
]
}
},
{
"_id" : ObjectId("5391b11a3c0a9ac01300006d"),
"injurydata" : {
"injuryinformation" : [
{
"status" : "current",
"updateddate" : ISODate("2014-06-06T12:16:20.306Z"),
"dateofinjury" : ISODate("2014-06-28T18:30:00.000Z"),
"_id" : ObjectId("5391b11a3c0a9ac01300006f")
}
]
}
},
{
"_id" : ObjectId("5391b11a3c0a9ac01300006d"),
"injurydata" : {
"injuryinformation" : [
{
"status" : "current",
"dateofinjury" : ISODate("2014-08-10T18:30:00.000Z"),
"_id" : ObjectId("5391b11a3c0a9ac01300006f")
}
]
}
}]
在此文档中,我只需要injuryinformation
在2014-06-28和2014-06-30之间的那些injuryinformation
数组元素,所以我只会得到前两个元素.
From this document, I want only those injuryinformation
array elements for which dateofinJURY
is between 2014-06-28 and 2014-06-30, so I will only get first two elements.
我尝试了此查询,但仍然可以得到整个数组
I tried this query but I still get the whole array
db.user.find(
{
$and:
[
{"injury.injurydata.injuryinformation.dateofinjury":
{"$gte": ISODate("2014-05-21T08:00:00Z") , "$lt": ISODate("2014-06- 03T08:00:00Z")}},
{"_id":ObjectId("538d9a1dd173e5202a00005d")}
],
})
推荐答案
_id
匹配在您的语句中相当明确,因此不仅会否定对数组条目进行范围"匹配的需要,而且还会否定 $and
的任何用法实际上在MongoDB查询中是隐式的. $and
条件本质上是除非您实际上是在同一字段上要求多个条件,否则不需要默认".但是你不在这里.
Well the _id
match is fairly explicit in your statement so not only will that negate the need for the "range" match on array entries but it also negates any usage of $and
which is actually implicit in MongoDB queries. The $and
condition is essentially the "default" and is not required unless you are actually asking for multiple conditions on te same field. But here you are not.
匹配多个数组元素需要使用 .aggregate()
作为.find()
可用的投影",不能向您显示来自数组的一个匹配条目:
Matching multiple array elements you need to use .aggregate()
as the "projection" available to .find()
cannot show you more than one matching entry from an array:
db.collection.aggregate([
// Match the document but not actually the array
{ "$match": {
"injury.injurydata.injuryinformation.dateofinjury": {
"$gte": ISODate("2014-05-21T08:00:00Z"),
"$lt": ISODate("2014-06-03T08:00:00Z")
},
"_id": ObjectId("538d9a1dd173e5202a00005d")
}},
// Unwind the arrays to "de-normalize" as documents
{ "$unwind": "$injury" },
{ "$unwind": "$injury.injurydata" },
{ "$unwind": "$injury.injurydata.injuryinformation" },
// Match the actual array elements
{ "$match": {
"injury.injurydata.injuryinformation.dateofinjury": {
"$gte": ISODate("2014-05-21T08:00:00Z"),
"$lt": ISODate("2014-06-03T08:00:00Z")
}
}},
// Group those back to and array, maybe?
{ "$group": {
"_id": "$_id",
"information": {
"$push": "$injury.injrydata.injuryinformation"
}
}}
])
或使用 $map
进行过滤" 在MongoDB 2.6和更高版本中,看起来更长但更快:
Or "filtering" with $map
under MongoDB 2.6 and greater, looks longer but faster:
db.collection.aggregate([
// Match the document but not actually the array
{ "$match": {
"injury.injurydata.injuryinformation.dateofinjury": {
"$gte": ISODate("2014-05-21T08:00:00Z"),
"$lt": ISODate("2014-06-03T08:00:00Z")
},
"_id": ObjectId("538d9a1dd173e5202a00005d")
}},
// Unwind the arrays to "de-normalize" as documents
{ "$unwind": "$injury" },
{ "$unwind": "$injury.injurydata" },
// Project with the "$map" filter
{ "$project": {
"information": {
"$setDifference": [
"$map": {
"input": "$injury.injurydata.injuryinformation",
"as": "el",
"in": {
"$cond": [
{
"$and": [
{
"$gte": [
"$$el.dateofinjury",
ISODate("2014-05-21T08:00:00Z")
]
},
{
"$lt": [
"$$el.dateofinjury",
ISODate("2014-06-03T08:00:00Z")
]
}
]
}
],
false
}
},
[false]
]
}
}}
])
所使用的 $和条件存在另一种形式,可用于 $match
操作之外的聚合框架表达式,这些表达式等效于.find()
查询
The $and condition used in there is a different form that is available to aggregation framework expressions outside of $match
operations that are equivalent to .find()
queries.
不确定伤害"顶线从哪里来,因为它在您的样本中没有显示,但是我认为您确实有.
Not sure where the "injury" top line comes from there as it is not represented in your sample, but I assume you actually have it.
这篇关于获取日期范围内的数组元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!