猫鼬— findOneAndUpdate()导致文档重复

时间:2019-10-13 16:34:22

标签: node.js mongodb mongoose

我正在将findOneAndUpdate()upsert: true一起使用,以便对文档进行更新(如果存在),否则将其创建。 tracks变量包含Track个实例的数组。 tracks确实包含一些重复项,这就是问题开始的地方。它使第7行(Observation.findOneAndUpdate(...))上的代码段创建(少量)重复项,即,多个具有相同(user, track)对的文档。请注意,这些重复项是随机插入的:运行两次此代码会带来不同的重复项文档。我的猜测是,这与在MongoDB中如何完成数据锁定有关,并且我同时进行了太多操作。关于如何克服这个问题的任何想法吗?

const promises = [];
​
tracks.forEach((track) => {
    const query = { user, track };
    const options = { new: true, upsert: true };
    const newOb = { user, track, type: 'recent' };
    promises.push(Observation.findOneAndUpdate(query, newOb, options));
});
​
return Promise.all(promises);

我正在使用mongoose 5.5.8和节点11.10.0

这是Observation模型:

const { Schema } = mongoose;

const ObservationSchema = new Schema({
  track: { type: Schema.Types.ObjectId, ref: 'Track' },
  user: { type: Schema.Types.ObjectId, ref: 'User' },
  type: String
});

ObservationSchema.index({ track: 1, user: 1 }, { unique: true });

const Observation = mongoose.model('Observation', ObservationSchema);

这是tracks数组包含的示例:

[
    { artists: [ 5da304b140185c5cb82d7eee ],
      _id: 5da304b240185c5cb82d7f48,
      spotifyId: '4QrEErhD78BjNFXpXDaTjH',
      __v: 0,
      isrc: 'DEF058230916',
      name: 'Hungarian Dance No.17 In F Sharp Minor',
      popularity: 25 },
    { artists: [ 5da304b140185c5cb82d7eee ],
      _id: 5da304b240185c5cb82d7f5d,
      spotifyId: '06dn1SnXsax9kJwMEpgBhD',
      __v: 0,
      isrc: 'DEF058230912',
      name: 'Hungarian Dance No.13 In D',
      popularity: 25 }
]

谢谢:)

1 个答案:

答案 0 :(得分:1)

我认为这是由于您的Promise.all方法造成的。

您应该等待循环中的每个查询,而不是最后等待所有内容。这是一个带有find的示例:

    async function retrieveApples() {
        const apples = [];
        arr.forEach(apple => {
            const foundApple = await AppleModel.findOne({ apple });
            apples.push(foundApple);
        }); 
    return apples
}