这是我的MongoDB集合中的示例文档:
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之间的dateofinJURY
数组元素,所以我只会得到前两个元素。
我尝试了这个查询,但我仍然得到整个数组
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")}
],
})
答案 0 :(得分:2)
_id
匹配在你的语句中是相当明确的,这样不仅会否定对数组条目的“范围”匹配的需要,而且它也会否定$and
的任何使用,这实际上是隐含的在MongoDB查询中。 $and
条件基本上是“默认”,除非您实际上要求同一字段上的多个条件,否则不需要.aggregate()
条件。但在这里你不是。
匹配多个数组元素,您需要使用$map
作为.find()
可用的“投影”,不能向您显示来自数组的一个匹配条目:
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"
}
}}
])
或者在MongoDB 2.6及更高版本下使用{{3}}进行“过滤”,看起来更长但更快:
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
操作之外的聚合框架表达式,等同于。{{ 1}}查询。
不确定“伤害”顶线来自哪里,因为它没有在您的样本中显示,但我认为您确实拥有它。