4

How to add multiple objects to array based on key?

I need to add multiple objects in one query, check if each object key doesn't exist or duplicate, else add object. (label can be duplicate)

Schema

new Schema({
      additional: [
        {
          key: { type: String, required: true, unique: true },
          label: { type: String, required: true }
        }
      ]
})

request payload:

[ {key: "city", label: "CITY"}, {key: "gender", label: "GENDER"}
, {key: "city" ,label: "CITY1"}, {key: "city2", label: "CITY"}]

Expected results:

[
 {key: "city", label: "CITY"},
 {key: "gender", label: "GENDER"},
 {key: "city2", label: "CITY"}
]

I tried to find solutions but couldn't find any.

2 Answers 2

3

You can try using bulkWrite operation in mongodb

Suppose you have following payload to update

const payload = [
  { key: "city", label: "CITY" }, { key: "gender", label: "GENDER" },
  { key: "city", label: "CITY1" }, { key: "city2", label: "CITY" }
]

Query to update documents in bulk

Model.bulkWrite(
  payload.map((data) => 
    ({
      updateOne: {
        filter: { '_id': 'xxxx', 'additional.key' : { $ne: data.key } },
        update: { $push: { additional: data } }
      }
    })
  )
})

Which will send a request in bulk to update like this

bulkWrite([
  { updateOne: { filter: { '_id': 'xxxx', 'additional.key' : { $ne: data.key } }, update: { $push: { additional: data } } } },
  { updateOne: { filter: { '_id': 'xxxx', 'additional.key' : { $ne: data.key } }, update: { $push: { additional: data } } } }
])
Sign up to request clarification or add additional context in comments.

3 Comments

doesn't work for me. it's add empty doc. did you test that?
it works fine, just have to add _id: 'xxxxx' of specific doc
0

One way to do it since mongoDB version 4.4 is using update with aggregation pipeline with a $merge step:

  1. $addFields with data to add and create a new keys field that contains the existing keys.
  2. $filter the data to include only items with keys that are not in the original array called 'additional'.
  3. $concatArrays: 'additional' and the filtered data array.
db.collection.aggregate({_id: 'xxxx'}, [
  {
    $addFields: {
      data: [{key: "city", label: "CITY"}, {key: "city2", label: "CITY"}],
      keys: "$additional.key"
    }
  },
  {
    $set: {
      data: {
        $filter: {
          input: "$data",
          as: "item",
          cond: {$not: {$in: ["$$item.key", "$keys"]}}
        }
      }
    }
  },
  {
    $set: {
      additional: {$concatArrays: ["$additional", "$data"]},
      data: "$$REMOVE", keys: "$$REMOVE"
    }
  }
])

Playground example

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.