Search code examples
mongodbmongodb-queryupdating

How to selectively remove field in documents in MongoDB collection according to binary field size?


I found $binarySize, but it can only be applied on aggregate queries, which makes completely new collection, which is not the dataset itself I want to make changes to.

I don't see a way to use $binarySize with find().

My aggregate query is this:

    db.releases_details.aggregate([
        { $project: { release_id: "$release_id", cover: "$cover", img: "$img", tracklist: "$tracklist", imageSize: { $binarySize: "$cover" } }  },
        { $match: { "imageSize": { $lt: 1775 } } }
    ])

Here's the sample data:

{ "_id" : ObjectId("623ebe3315e29330ede4e631"), "release_id" : 43239, "cover" : BinData(0,"PCFET0NUWVBFIGh0bWw+CjxodG1sIGxh... (1,555 bytes)") },
{ "_id" : ObjectId("623ebe3315e29330ede4e630"), "release_id" : 43238, "cover" : BinData(0,"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBD... (42,200 bytes - image/jpeg)") }

If only I can set cover property to null wherever it is smaller than 1775 bytes?

Anyone did something similar?


Solution

  • You can do the manipulate the cover field with $cond. Then use $merge to update back into the collection with an aggregation pipeline.

    db.collection.aggregate([
      {
        "$addFields": {
          "cover": {
            "$cond": {
              "if": {
                $lt: [
                  {
                    "$binarySize": "$cover"
                  },
                  1775
                ]
              },
              "then": null,
              "else": "$cover"
            }
          }
        }
      },
      {
        "$merge": {
          "into": "collection",
          "on": "_id",
          "whenMatched": "replace"
        }
      }
    ])
    

    Here is the Mongo playground for your reference.