猫鼬:findOneAndUpdate不更新现有字段

时间:2019-11-19 20:06:57

标签: javascript node.js mongodb mongoose

我试图每分钟将Web API数据提取到MongoDB,保存并在发生任何更改时进行更新。问题在于,只有将新的volume添加到date-子文档中时,ChildSchemaData(每个字段)字段才被更新(在新交易日开始后发生)。所有这些数据都用于在前端建立每日(而非每小时/分钟)库存图表。而且我正在尝试从数据库中流式传输它,但是由于volume(以及子文档中的所有其他字段)没有在数据库中更新,因此前端没有任何更改。我试图实现更改Streams MongoDB(数据库中的数据流),所以我坚持要从数据库中获取数据。任何帮助表示赞赏。谢谢!

Edit1 $addToSet运算符将一个值添加到数组,除非该值已经存在,在这种情况下,$addToSet对该数组不执行任何操作。看起来就是问题所在。我想知道是否还有其他运算符可以更新已经存在的值。

Edit2 :我正在使用以下语法,但不确定是否正确

const update = {
      $addToSet: { data: webApiData },
      $set: { 'data[0].$.volume': webApiData[0].volume },
    };  

因为它进入了相同的path,将无法正常工作

控制器

const creatStock = async (symbol, webApiData) => {
  try {
    const query = { symbol };
    const update = { $addToSet: { data: webApiData } };
    const options = { upsert: true, new: true };

    await Stock.findOneAndUpdate(query, update, options);
  } 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,
  },
  // Array of subdocuments
  data: [ChildSchemaData],
});

2 个答案:

答案 0 :(得分:0)

srinivasy通过以下链接link

提供了此解决方案
const creatStock = async (symbol, webApiData) => {
  try {
    // reversed array
    const webApiDataReversed = webApiData.reverse();
    const query = { symbol };

    const position = await Stock.findOne(query);

    if (!position) {
      console.log('New stock'.green);
      return Stock.create({
        symbol,
        data: webApiDataReversed,
      });
    }

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

答案 1 :(得分:0)

如果要更新数组中的元素,可以考虑使用positional operator: $并将字段添加到更新查询中。

这将标识数组中的元素以根据条件进行更新。

使用volume字段等于100并设置为200来更新嵌入式阵列的示例:

db.getCollection("collection").findOneAndUpdate({
    id: 1,
    "data.volume": 100
}, 
    { $set: { "data.$.volume": 200 } 
});