我需要过滤两个日期(开始和结束)之间的数据,以仅在前面显示所选日期之间发生的事件...
产品 Controller 方法:
async show(req, res){
const { product_id, dt_ini, dt_fin } = req.params;
let dtIni = new Date(dt_ini);
let dtFin = new Date(dt_fin);
dtIni = dtIni.toISOString();
dtFin = dtFin.toISOString();
let product = await Product.findOne({ product_id });
if(product){
product = await product.populate('event').execPopulate();
await product.find({"event.timestamp": {'$gte': dtIni,'$lt': dtFin}});
}else{
return res.status(404).json({ error: `Product not found.`});
}
return res.json(product);
}
模型事件:
const mongoose = require('mongoose');
const EventSchema = new mongoose.Schema({
product_id: String,
timestamp: Date,
created_by: String,
description: String,
sale_price: Number,
list_price: Number,
has_discount: Boolean,
url: String,
warehouse: String,
page_type: String,
showcase:{
name: String,
position : Number
},
});
module.exports = mongoose.model('Event', EventSchema);
模型产品:
const mongoose = require('mongoose');
const ProductSchema = new mongoose.Schema({
product_id: Number,
product_sku: String,
product_name: String,
product_brand: String,
product_category: String,
event: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Event'
}
],
});
module.exports = mongoose.model('Product', ProductSchema);
在 MongoDB populate()
之后我收到这个错误:
(node:3496) UnhandledPromiseRejectionWarning: TypeError: product.find is not a function
我错过了什么?
最佳答案
你可以做一个条件填充:
async show(req, res){
try {
const { product_id, dt_ini, dt_fin } = req.params;
if(!product_id || !dt_ini || !dt_fin)
throw "You must supply a product id with start and end dates!";
const existingProduct = await Product
.findOne({ product_id })
.populate("event", null, { timestamp: { $gte: new Date(dt_ini), $lte: new Date(dt_fin) } })
if(!existingProduct)
throw "Unable to locate any product events in that date range.";
res.status(200).json({ product: existingProduct });
} catch(e) {
res.status(404).json({ error: e.toString() });
}
}
或者,您可以执行 aggregated查询:
这是一个简化的工作 Playground :https://mongoplayground.net/p/YGiywDCkR-2
async show(req, res){
try {
const { product_id, dt_ini, dt_fin } = req.params;
if(!product_id || !dt_ini || !dt_fin)
throw "You must supply a product id with start and end dates!";
const existingProduct = await Product.aggregate([
// match against the product id
{ $match: { product_id } },
// lookup (populate) the "event" field with event data as "events"
{
$lookup: {
from: "events",
localField: "event",
foreignField: "_id",
as: "events"
}
},
// spread out the populated "events" field
{ $unwind: "$events"},
// filter the "events.timestamp" with dates
{
$match: {
"events.timestamp": {
"$gte": new Date(dt_ini),
"$lte": new Date(dt_fin)
}
}
}
]);
if(existingProduct.length === 0)
throw "Unable to locate any product events in that date range.";
res.status(200).json({ product: existingProduct });
} catch(e) {
res.status(404).json({ error: e.toString() });
}
}
不过,使用 $lookup
时要小心,因为它可能非常昂贵。
关于javascript - 如何过滤 Mongoose 中的日期事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59415979/