【问题标题】:How to add new property to mongoDb model?如何向 mongoDb 模型添加新属性?
【发布时间】:2021-10-18 04:25:43
【问题描述】:

您好,我正在创建一个项目,根据其类别显示所有硬币的 PopulationCount 数据中的用户变化。

我创建了一个 NodeJS 脚本来从一个硬币网站上抓取数据,并将其保存在我的 MongoDB 云数据库中,如下所示。

在前端,我创建了一个 React 应用程序,如下所示: 当用户点击一个硬币类别时,它应该显示今天的所有硬币

这是与显示我的路线中所有硬币类别相关的代码:

 router.get(
    "/categories",
   asyncHandler(async (req, res) => {
    const categories = await Coin.find().distinct(
      "category",
      (err, results) => {
        res.json(results);
      }
    );
  })
);

我的生活遇到了最大的问题/麻烦,因为我需要在此文档中添加新属性,以计算 PopulationCount 与今天日期和昨天日期之间的差异,然后将这个新的“趋势”属性添加到文档中。

这样我就可以显示今天日期的硬币数据和计算出的“趋势”属性,以确定它的价值是减少还是增加。

我怎样才能做到这一点?到目前为止,我已经编写了这段代码,但我不知道从哪里开始。

router.get(
  "/categories/:category",
  asyncHandler(async (req, res) => {
    const { category } = req.params;
    const fullName = category.replace(/-/g, " ");

    // todays coins
    const today = new Date(Date.now());
    today.setHours(0, 0, 0, 0);
    const todaysCoins = await Coin.find({
      category: {
        $regex: new RegExp(fullName, "i"),
      },
      createdAt: {
        $gte: today,
      },
    }).lean();
    res.json(todaysCoins);

    // loop thru all todays coins
    // compare to yesterdays coins
      // loop thru array of today and compare to yesterday and add trend
  })

// loop through yesterdays coins

const startYest = new Date(Date.now());
startYest.setHours(0, 0, 0, 0);
const oneDayAgo = startYest.getDate() - 1;
startYest.setDate(oneDayAgo);

const endYest = new Date(Date.now());
endYest.setHours(23, 59, 59);
const endYestDayAgo = endYest.getDate() - 1;
endYest.setDate(endYestDayAgo);
const yesterdayCoins = await Coin.find({
  category: {
    $regex: new RegExp(fullName, "i"),
  },
  createdAt: {
    $gte: startYest,
    $lt: endYest,
  }
}).lean()
);

【问题讨论】:

  • MongoDB 不允许你动态添加属性到模型中,我的建议是,第一次创建模型时,将Trend 属性添加到默认值,然后计算差异只是更新Trend 值。
  • 我对猫鼬完全不熟悉,但是可以用$addFields和聚合:docs.mongodb.com/manual/reference/operator/aggregation/…来完成吗?

标签: reactjs mongodb mongoose


【解决方案1】:

即使在 Node.js 中创建模型之后,我也能够在模型中添加新属性:

insertMany(table_data, { strict: false });

其中 table_data 包含附加了新属性的旧数据。 strict: false 创造了奇迹。

节点中的订单模型:

const mongoose = require ('mongoose');

const OrdersSchema = new mongoose.Schema({
  sr_no :{type: Number, required:true},
  customer_name :{type: String, required:true},
  product_name: String,
  codes: String,
  code_date:{
    type:Date,
    default: Date.now()
  },
  design : String,
  design_date :{
    type:Date,
    default: Date.now()
  },
  design_approval :{
    type:String,
    default: ''
  },
  design_approval_date :{
    type:Date,
    default: Date.now()
  },
  send_to_printer :{
    type:String,
    default: ''
  },
  send_to_printer_date :{
    type:Date,
    default: Date.now()
  },
  proof_approval :{
    type:String,
    default: ''
  },
  proof_approval_date :{
    type:Date,
    default: Date.now()
  },
  shipping : String,
  ship_date :{
    type:Date,
    default: Date.now()
  },
  received :{
    type:String,
    default: ''
  },
  received_date :{
    type:Date,
    default: Date.now()
  },
  completed : String,
  notes : String,
  printing :{
    type:String,
    default: ''
  },
  printing_date :{
    type:Date,
    default: Date.now()
  },
  stapling :{
    type:String,
    default: ''
  },
  stapling_date :{
    type:Date,
    default: Date.now()
  },
  user_id :{type: Number, required:true}
},{strict: false});

OrdersSchema.index({ sr_no: -1 });

const Orders = mongoose.model(
  'Orders',
  OrdersSchema
);

module.exports = Orders;

在 Mongo Compass 中,第一条记录如下所示:

同一集合中的另一条记录是:

【讨论】:

    【解决方案2】:

    正如 Sharrzard Gh 所说,MongoDB 不允许您在定义模型后向其添加新属性。相反,请使用这样的结构来定义一个最初为空的属性,稍后您将使用它来存储趋势数据。

    const CoinSchema = new Schema({
      specName: { type: String, required: true },
      fullName: { type: String, required: true },
      category:{ type: String, required: true },
      coinName: { type: String, required: true },
      trend: { type: String, required: true, default: '' }  // <- Add this property
    });
    
    module.exports = mongoose.model("coins", CoinSchema);
    

    如果您需要存储更复杂的数据或用于历史趋势跟踪的一系列数据点,您可以将趋势数据类型更改为数组或对象。

    试试这样的:

    trend: { type: Object, required: true, default: {} }
    

    trend: { type: [String] , required: true, default: [] }
    

    【讨论】:

    • 这也有效吗?我对 MongoDB docs.mongodb.com/manual/reference/operator/aggregation/… 完全陌生@ 我还需要做一个嵌套循环来循环遍历今天的硬币,然后循环遍历那个硬币中的数组吗?我如何与昨天的硬币进行比较?对不起..我还是初级,无法弄清楚
    • 因此,您不能在模型定义后向模型添加新属性。相反,您创建一个空属性,然后在那里添加您的计算,以进行跟踪。这是在 React 中使用 map 进行嵌套循环的方法。 stackoverflow.com/questions/47402365/… 您可能需要地图或 forEach。 Maps 返回一个数组,forEach 没有。 JS 中的比较看起来像这样w3schools.com/js/js_comparisons.asp
    • @julzoh 如果我的回答对您有所帮助,请接受它(侧面的小绿色复选框)并奖励我您对问题的赏金。这有助于鼓励像我这样的人花时间为你的问题写答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 1970-01-01
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-12
    相关资源
    最近更新 更多