1

I was wondering if there is a better way to update an existing element in an array instead of fetching database three times. If you have any ideas I would appreciate it. Thank you!

    const creatStock = async (symbol, webApiData) => {
      try {
        // reversed array
        const webApiDataReversed = webApiData.reverse();

        const query = { symbol };
        const update = { $addToSet: { data: webApiDataReversed } };
        const options = { upsert: true, new: true };
        // create/update Stock
        const stockResult = await Stock.findOneAndUpdate(query, update, options);
        const lastElement = stockResult.data.length - 1;

        const updatePull = {
          $pull: { data: { date: stockResult.data[lastElement].date } },
        };
        // removes last date from data array
        await Stock.findOneAndUpdate(query, updatePull);
        // update Stock
        await Stock.findOneAndUpdate(query, update);
      } catch (ex) {
        console.log(`creatStock error: ${ex}`.red);
      }
    };

Schema

const ChildSchemaData = new mongoose.Schema({
  _id: false,
  date: { type: mongoose.Types.Decimal128 },
  open: { type: mongoose.Types.Decimal128 },
  high: { type: mongoose.Types.Decimal128 },
  low: { type: mongoose.Types.Decimal128 },
  close: { type: mongoose.Types.Decimal128 },
  volume: { type: mongoose.Types.Decimal128 },
});

const ParentSchemaSymbol = new mongoose.Schema({
  symbol: {
    type: String,
    unique: true,
  },
  // Array of subdocuments
  data: [ChildSchemaData],
});

module.exports.Stock = mongoose.model('Stock', ParentSchemaSymbol);

Output

enter image description here

3
  • Can you please show the sample doc & expected o/p, that way it would be easy on this question... Commented Nov 21, 2019 at 22:27
  • @srinivasy the original question updated with schema and the output Commented Nov 22, 2019 at 4:00
  • If all you need is to remove the last element in the array & update the array with a new input element only if there is no duplicate found in the array, then try below one. Commented Nov 22, 2019 at 5:55

2 Answers 2

1

Well, if you don't need to return the updated document, Please try this one - this will just return a write result, with this things can be achieved in one DB call :

const creatStock = async (symbol, webApiData) => {
    try {
        // reversed array
        const webApiDataReversed = webApiData.reverse();
        const query = { symbol };

        await Stock.bulkWrite([
            {
                updateOne:
                {
                    "filter": query,
                    "update": { $pop: { data: 1 } }
                }
            }, {
                updateOne:
                {
                    "filter": query,
                    "update": {
                        $addToSet: {
                            data: webApiDataReversed
                        }
                    }
                }
            }
        ])
    } catch (ex) {
        console.log(`creatStock error: ${ex}`.red);
    }
};

Ref : mongoDB bulkWrite

Sign up to request clarification or add additional context in comments.

Comments

0

you can do like this way :

  const creatStock = async (symbol, webApiData) => {
  try {
    // reversed array
    const webApiDataReversed = webApiData.reverse();

    const query = { symbol };

    let stock =  await Stock.findOne(query);
    if(stock){
       let stockData = JSON.parse(JSON.stringify(stock.data));
       if(stockData.length>0){
          stockData.pop(); 
       }
       stockData.concat(webApiDataReversed);
       stock.data = stockData;
       await stock.save();
    }
  } catch (ex) {
      console.log(`creatStock error: ${ex}`.red);
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.