我的文档如下:
> db.users.find().pretty()
{
"_id" : ObjectId("52ee0844177c86dc1d000001"),
"profile" : {
"displayName" : "Sydney",
},
"todos" : [
{
"date" : ISODate("2014-02-02T21:47:13.064Z"),
"value" : "#first in the #middle also but twice #middle and the #end",
"tags" : [
"#first",
"#middle",
"#end"
]
},
{
"date" : ISODate("2014-02-05T21:20:30.904Z"),
"value" : "Find mongo query #mongo #work",
"tags" : [
"#mongo",
"#work"
]
}
]
}
我想查询待办事项的日期范围:
> var start = new Date()
> var end = new Date()
> start.setDate(start.getDate() - 2)
1391544140700
> start
ISODate("2014-02-04T20:02:20.700Z")
> end
ISODate("2014-02-06T20:02:25.828Z")
>db.users.find({todos: {$elemMatch: {date: { $gte: start, $lt: end }}}}, {'todos':1}).pretty()
但查询仍会返回两条记录。我原以为只能拿到最后一个。
答案 0 :(得分:2)
来自文档:
如果多个元素与$ elemMatch条件匹配,则为运算符 返回数组中第一个匹配元素。
这是设计(限制),并且没有其他运算符只返回匹配的元素。一种方法是使用聚合框架来过滤返回的数组元素:
db.users.aggregate([
{$match: {todos: {$elemMatch: {date: { $gte: start, $lt: end }} } }},
{$unwind: "$todos"},
{$match:{"todos.date": { $gte: start, $lt: end } }},
{$group: { _id: { _id: "$_id", profile: "$profile" }, todos: {$push: "$todos" } } },
{$project: {_id: "$_id._id", profile: "$_id.profile", todos: 1 } }
])
如果只需要一个字段,请将positional运算符与$ elemMatch结合使用,仅返回匹配项,因为在投影中重新设置$ elemMatch是没有多大意义的。
{todos: {$elemMatch: {date: { $gte: start, $lt: end }}}}, {"todos.$": 1}