How to add new property to mongoDb model?

Viewed 706

Hello I am creating a project to show user changes in the PopulationCount data of all the coins according to their categories.

I created a NodeJS script to scrape the data from a coin website, and I have saved it in my MongoDB cloud database as shown below.

MongoDB

In the Front-End, I have created a React App as shown: When user clicks on a coin category, it should display all the coins from today enter image description here

Here is the code that relates to showing all the Coin's Categories in my route:

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

I am having the biggest problem/trouble with my life because I need to add new property to this document that calculates the difference of the PopulationCount from Today's Date and Yesterday's Date and then adding this new "Trend" property to the document.

So that I can display the Coin data from Today's date and the calculated "trend" property that determines if it there was a decrease or increase in value.

How can I achieve this? So far I have written this code, but I do not know where to go from here.

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()
);
2 Answers

As Sharrzard Gh said, MongoDB doesn't allow you to add a new property to your model after it's been defined. Instead, use a structure like this, to define an initially empty property that you will use later to store the trend data.

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);

You can change the trend data type to an array or object if you need to store more complex data or a series of data points for historical trend tracking, if you want.

Try something like this:

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

or

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

I was able to add new properties in the model even after the creation of the model in Node.js using:

insertMany(table_data, { strict: false });

where table_data container the old data appended with the new properties. The strict: false did the magic.

Order Model in Node:

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;

In Mongo Compass the first record appeared like: enter image description here

And another record in the same collection was:

enter image description here

Related