javascript - 如何过滤 Mongoose 中的日期事件?

标签 javascript reactjs mongodb mongoose

我需要过滤两个日期(开始和结束)之间的数据,以仅在前面显示所选日期之间发生的事件...

产品 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/

相关文章:

javascript - 从 Node HTTP 请求中运行的算法需要更长的时间来运行

内存中的 MongoDB 索引与分片

python - 使用 Spark-DataFrame 将 HDFS 保存到 MongoDB

javascript - Django:如何创建一个随用户点击而变化的动态表单?

Javascript 原型(prototype)语法

android - react native Flatlist renderItem 不更新

javascript - 在 React 中隐藏 HTML 元素

reactjs - 如何根据用户输入动态设置组件的属性?

javascript - fb.api 在连接的用户上返回 'undefined'

javascript - 如何将元素个性化为唯一标识符?