【发布时间】:2020-02-01 02:51:32
【问题描述】:
我想聚合一个给定类型的集合。类型来自查询字符串,可以是日、月或年。根据用户选择我想要分组的类型。 例如:如果用户选择“月”,我想按月分组。
Event.aggregate([
{
$lookup: { from: Product.collection.name, localField: 'product', foreignField: '_id', as: 'product' }
},
{
$group: {
_id: { $month: { date: "$date" } },
price: { $sum: "$price" },
result: { $mergeObjects: { name: "$product.name", _id: "$product._id" } },
count: { $sum: 1 }
},
},
]).then(response => {
console.log(response)
res.send(response)
})
我不知道如何找到干净的解决方案。 到目前为止,我发现的唯一方法是在 Model.aggregate([]) 之前使用 if 条件 ...
if (req.query.dateAvailability && req.query.dateAvailability === 'month') {
Event.aggregate([
{
$lookup: { from: Product.collection.name, localField: 'product', foreignField: '_id', as: 'product' }
},
{
$group: {
_id: { $month: { date: "$date" } },
price: { $sum: "$price" },
result: { $mergeObjects: { name: "$product.name", _id: "$product._id" } },
count: { $sum: 1 }
},
},
]).then(response => {
console.log(response)
res.send(response)
})
} else if (req.query.dateAvailability && req.query.dateAvailability === 'day') {
Event.aggregate([
{
$lookup: { from: Product.collection.name, localField: 'product', foreignField: '_id', as: 'product' }
},
{
$group: {
_id: { $dateToString: { format: "%d-%m-%Y", date: "$date" } },
price: { $sum: "$price" },
result: { $mergeObjects: { name: "$product.name", _id: "$product._id" } },
count: { $sum: 1 }
},
},
]).then(response => {
console.log(response)
res.send(response)
})
} else if (req.query.dateAvailability && req.query.dateAvailability === 'year') {
Event.aggregate([
{
$lookup: { from: Product.collection.name, localField: 'product', foreignField: '_id', as: 'product' }
},
{
$group: {
_id: { $year: { date: "$date" } },
price: { $sum: "$price" },
result: { $mergeObjects: { name: "$product.name", _id: "$product._id" } },
count: { $sum: 1 }
},
},
]).then(response => {
console.log(response)
res.send(response)
})
}
模型事件:
const EventSchema = new Schema({
client: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Client'
}]
},
product: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Product'
}]
},
date: {
type: Date,
maxlength: 64,
lowercase: true,
trim: true
},
place: {
type: String,
maxlength: 1200,
minlength: 1,
},
price: {
type: Number
},
comment: {
type: String,
maxlength: 12000,
minlength: 1,
},
status: {
type: Number,
min: 0,
max: 1,
default: 0,
validate: {
validator: Number.isInteger,
message: '{VALUE} is not an integer value'
}
},
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
},
{
timestamps: true
},
);
【问题讨论】:
-
谢谢汤姆斯巴伯特和乔什巴尔奇蒂斯,这两种解决方案都很完美,而且比我的更干净(我测试过它们)。很高兴知道在这种情况下也没有消除逻辑的神奇解决方案。我会接受汤姆的回答,因为它是第一个,但两者都是使代码更清晰的好方法。
标签: mongodb aggregation-framework aggregate