我有以下Mongoose架构:
let ExerciserSchema = new Schema({
username: {
type: String,
required: true
},
exercises: [{
desc: String,
duration: Number,
date: {
type: Date,
default: new Date()
}
}]
});
我想按用户名搜索并将练习结果限制为日期范围。
我尝试了这个查找功能:
let user = await Exerciser.find(
{ "username": name },
{ "exercises.date": { "$gte": from }},
{ "exercises.date": { "$lte": to }}
).exec((err, data) => {
if (err) {
res.json({ Error: "Data not found" })
return done(err);
}
else {
res.json(data);
return done(null, data);
}
});
但是,它记录错误而不返回数据。
MongoError: Unsupported projection option: exercises.date: { $gte: new Date(1526342400000) }
我从这个错误中意识到我的日期正在以毫秒为单位进行搜索,但我console.log
就在我运行上述函数之前,它处于日期模式,这就是我想要的:{ {1}}
如何才能完成这项工作,以便根据我的架构搜索日期范围?如有必要,我可以在Schema中更改日期的格式。我只想要最简单的解决方案。谢谢你的帮助。
答案 0 :(得分:1)
你的查询错了。您试图写一个AND条件,但是您将文档分开而不是将所有内容放在一起。这意味着Model.find()
的“第二个”参数被解释为“字段投影”,因此错误:
MongoError:不支持的投影选项:
所以这不是“架构问题”,而是你向Model.find()
方法发送了错误的参数
对于数组中元素的多个条件,您还需要$elemMatch
:
// Use a try..catch block with async/await of Promises
try {
let user = await Exerciser.find({
"username": name,
"exercises": {
"$elemMatch": { "date": { "$gte": from, "$lte": to } }
}
});
// work with user
} catch(e) {
// handle any errors
}
最重要的是,你没有await
回调。您await
Promise
就像我在这里展示的那样,或者只是传递callback
。不是两个。
Exerciser.find({
"username": name,
"exercises": {
"$elemMatch": { "date": { "$gte": from, "$lte": to } }
}
}).exec((err,user) => {
// the rest
})
仅供参考,您试图做的是:
Exerciser.find({
"$and": [
{ "username": name },
{ "exercises.date": { "$gte": from }},
{ "exercises.date": { "$lte": to }}
]
)
但实际上这仍然是不正确的,因为没有$elemMatch
$gte
和$lte
适用于数组的所有元素而不仅仅是单个元素。因此,如果ANY数组项小于日期但不一定大于。
对于数组元素,$elemMatch
强制执行两个条件之间的“之间”。
答案 1 :(得分:0)
我设法得到它。此答案与用户名匹配,并过滤练习,因此它们位于变量名称为to
和from
的日期之间。这就是我想要的。
let user = Exerciser.aggregate([
{ $match: { "username": id }},
{ $project: { // $project passes along the documents with the requested fields to the next stage in the pipeline
exercises: { $filter: {
input: "$exercises",
as: "exercise",
cond: { $and: [
{ $lte: [ "$$exercise.date", to ] },
{ $gte: [ "$$exercise.date", from ] },
]}
}},
username: 1, // include username in returned data
_id: 0
}}
])
结果:
[
{
"username": "scott",
"exercises": [
{
"desc": "Situps",
"duration": 5,
"_id": "5af4790fd9a9c80c11aac696",
"date": "2018-04-30T00:00:00.000Z"
},
{
"desc": "Situps",
"duration": 10,
"_id": "5afb3f03e12e38020d059e67",
"date": "2018-05-01T00:00:00.000Z"
},
{
"desc": "Pushups",
"duration": 8,
"_id": "5afc08aa9259ed008e7e0895",
"date": "2018-05-02T00:00:00.000Z"
}
]
}
]