1

I have to update an array inside a document on the basis of a string which i get from the req.value.

My collection

[
  {
    "_id": 1,
    "key": [
      "1-value-1",
      "1-value-2"
    ]
  },
  {
    "_id": 2,
    "key": [
      "2-value-1",
      "2-value-2"
    ]
  }
]

I have another string newString. Let's assume two conditions:

  • when req.value is in the array in that case replace the array value with newString.
  • else rew.value is not present simple push the newString in the array.

Eg: I have a newString = 1-value-3 and req.value = 1-value-2 in that case replace array value 1-value-2 to 1-value-3. Else if req.value isn't in array push newString value to array.

This is the collection on which i want to perform operations on.

Thanks for answering in advance.

1
  • 2
    Please copy the input data directly into this question instead of linking to mongoplayground; it makes it easier for both new readers and answerers. Second: you write update to 1-value-3 if 1-value-2 exists else push 1-value-3 if 1-value-4 doesn't exist That is unclear. Please edit the question to show exactly what the desired output shape should be. Commented Apr 15, 2022 at 18:01

1 Answer 1

3

Update with pipeline

Query

  • if 1-value-2 exists change to 1-value-3
  • else `push 1-value-3 in the end of the array (i think you want this)
  • filter to check if it exists
  • if exists map to update
  • else concat to add in the end of the array

Playmongo(update,exists)
Playmongo(push(concat), missing)

update(
{"_id": {"$eq": 1}},
[{"$set": 
   {"v2-exists": 
     {"$ne": 
       [{"$filter": 
           {"input": "$key", "cond": {"$eq": ["$$this", "1-value-2"]}}},
         []]}}},
 {"$set": 
   {"key": 
     {"$cond": 
       ["$v2-exists",
         {"$map": 
           {"input": "$key",
            "in": 
             {"$cond": 
               [{"$eq": ["$$this", "1-value-2"]}, "1-value-3", "$$this"]}}},
         {"$concatArrays": ["$key", ["1-value-3"]]}]}}},
 {"$unset": ["v2-exists"]}])

Update operators

Query1(check if exists)

find({"_id": {"$eq": 1}, "key": {"$elemMatch": {"$eq": "1-value-2"}}})

If query1 empty result send this(push at the end)

update(
{"_id": {"$eq": 1}},
{"$push": {"key": "1-value3"}})

else send this (set to replace the old value)

update(
{"_id": {"$eq": 1}},
{"$set": {"key.$[m]": "1-value-3"}},
{"arrayFilters": [{"m": {"$eq": "1-value-2"}}]})
Sign up to request clarification or add additional context in comments.

8 Comments

Where's the update...?
its ok i fixed that, it was update with pipeline, and i forgot to change the method, the problem is that i am not sure if this is what he wants, if you understand what he wants maybe try to answer i am confused, and just tried.
What happened to a condition to check for 1-value-4? @ShubhamMaheshwari Expand the question to explain what is going on with the candidate string that is sent to the update.
i added alternative way, without aggregation update, that you will find probably simpler.Bu t its not atomic. And its 2 queries.
ok this answer does what you want i think, try one of those 2 ways, and i think you will be ok. if works accept it as solution also, this helps me and others to know if question has working answer.
|

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.