Two Horses
Two Horses

Reputation: 1702

Multiple updates on a single field causes "Updating the path 'X' would create a conflict at 'X'" in mongoDB

I have the following update operation:

private async onCategoryImagesModified(data: ModifiedFilesEventData) {
        this.categoryModel
            .findByIdAndUpdate(data.resourceId, {
                $pullAll: { images: data.removedFiles || [] },
                $addToSet: { images: { $each: data.addedFiles || [] } }
            }).catch(error => this.logger.warn(error))
}

Basically, every time images of model category changes I want to update the document by removing all the removed paths from images and adding the new paths to images.

I get that I can't reference the same field more than once inside an update, but is there a way to do this without 2 separate update operations?

Upvotes: 1

Views: 1055

Answers (1)

turivishal
turivishal

Reputation: 36124

I get that I can't reference the same field more than once inside an update

The update will not support the same field more than once, if you want to do this in the single query you can try update with aggregation pipeline starting from MongoDB 4.2,

  • $filter to iterate loop of images and remove the input elements by $not and $in
  • $setUnion to get unique elements from input elements and images field
private async onCategoryImagesModified(data: ModifiedFilesEventData) {
  let stages = [];
  // remove fields
  if (data.removedFiles) {
    stages.push({
      $set: {
        images: {
          $filter: {
            input: "$images",
            cond: { $not: { $in: ["$$this", data.removedFiles] } }
          }
        }
      }
    });
  }

  // add fields
  if (data.addedFiles) {
    stages.push({
      $set: { images: { $setUnion: ["$images", data.addedFiles] } }
    });
  }

  this.categoryModel
    .findByIdAndUpdate(data.resourceId, [stages])
    .catch(error => this.logger.warn(error))
}

Playground

Upvotes: 1

Related Questions