【问题标题】:Mongoose: How to update an existing element in array?Mongoose:如何更新数组中的现有元素?
【发布时间】:2019-11-22 13:49:17
【问题描述】:

我想知道是否有更好的方法来更新数组中的现有元素,而不是三次获取数据库。如果您有任何想法,我将不胜感激。谢谢!

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

架构

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

输出

【问题讨论】:

  • 能否请您显示示例文档和预期的 o/p,这样就可以轻松解决这个问题...
  • @srinivasy 使用架构和输出更新的原始问题
  • 如果您只需要删除数组中的最后一个元素并仅在数组中没有找到重复项的情况下使用新的输入元素更新数组,请尝试以下一个。

标签: javascript node.js mongodb mongoose


【解决方案1】:

好吧,如果您不需要返回更新后的文档,请试试这个 - 这只会返回一个写入结果,这样可以在一次 DB 调用中实现:

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

参考: mongoDB bulkWrite

【讨论】:

    【解决方案2】:

    你可以这样做:

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

    【讨论】:

      猜你喜欢
      • 2020-04-18
      • 2020-05-23
      • 2014-01-31
      • 2014-12-03
      • 2018-12-14
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多