ac3*_*360 0 javascript mongoose mongodb node.js aggregation-framework
如何使用mongoose/mongodb设计查询以在日期范围内进行搜索并提取该范围内每天的最高价格值?现在,我知道如何执行此操作的唯一方法是在日期范围内执行查询,然后处理结果以获取每天的最高价格.但这似乎是一个常见的需求,所以我想知道是否可以在查询中完成所有操作:
这是我的模型,它提供了一些可以在查询中使用的不同内容.该date属性是Date类型,day属性是字符串类型.该day属性采用这种格式day: "02/11/2014".该price属性是Number数据类型,它采用以下格式:price: 114.61
// Price Schema
var PriceSchema = new Schema({
full_date: {
type: String,
required: true,
unique: true,
trim: true
},
day: {
type: String,
required: true,
trim: true
},
price: {
type: Number,
required: true,
trim: true
},
date: {
type: Date,
unique: true,
required: true
}
});
Run Code Online (Sandbox Code Playgroud)
这是日期范围内的查询,但是我可以做类似于每个日期返回最高价格的事情吗?
Price.find({ date: { $lt: end, $gt: start }}, function(err, prices) {
if (err) {
console.log(err);
} else {
res.jsonp(poolprices);
}
});
Run Code Online (Sandbox Code Playgroud)
您可能希望使用聚合管道:
Price.aggregate([
// Match the date range
{ "$match": { "date": { "$lt": end, "$gt": start} } },
// Change document with date to a value just for the day
{ "$project":{
"date": {
"year": { "$year": "$date"},
"month": { "$month": "$date" },
"day": { "$dayOfMonth": "$date"}
},
"price": 1
}},
// Sort everything (descending so highest price per day is on top)
{ "$sort": { "date.year": -1, "date.month": -1, "date.day": -1, "price": -1 }},
// Group per day (now as a nice string), and keep the first price (highest)
{ "$group": {
"_id": {
"$concat": [{ "$substr": ["$date.year", 0, 4] },
"-",
{ "$substr": ["$date.month", 0, 2]},
"-",
{ "$substr": ["$date.day", 0, 2]}]
},
"price": { "$first": "$price"}
}},
// Make field names nicer
{ "$project": { "_id":0, "day": "$_id", "price": 1 } }
],
function(err,result) {
//process here
})
Run Code Online (Sandbox Code Playgroud)
因此,结果在您的范围内每天只有1个价格,并且无需以编程方式循环结果.
这是一个很好的小操作,它利用Date操作符来分解日期字段,然后使用$ substr和$ concat来为结果返回更好的值.考虑到您现在知道在这里可以做什么,您也可以重新考虑模式中的一些字段.