Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

arrayFilters in mongodb

I have the following schema.

{
   posts: [
          {
             _id: '5ayuunbdsyuuuyut778'
             replies: [{
                 _id: "67hfudj7e9whduu888",
                 text: "something"
             }]
          }
      ]
}

I want to update the text in particular reply. I am using mongoose.

I have written the query as follows

Post.findOneAndUpdate(
   {'posts.replies._id': _id}, 
   {$set: {'posts.$[post].replies.$[reply].text': "something1"}},
   { arrayFilters: [{'post._id': postId}, { 'reply._id': _id }]}
 )

This query is not updating the document.

Am I missing something? Do I need to cast ids using ObjectId

like image 874
Kodanda Rama Durgarao poluri Avatar asked Jul 13 '18 12:07

Kodanda Rama Durgarao poluri


People also ask

How do I update an embedded array in MongoDB?

To perform an update on all embedded array elements of each document that matches your query, use the filtered positional operator $[<identifier>] . The filtered positional operator $[<identifier>] specifies the matching array elements in the update document.

What is $[] in MongoDB?

Definition. $[] The all positional operator $[] indicates that the update operator should modify all elements in the specified array field. The $[] operator has the following form: { <update operator>: { "<array>.$[]" : value } }

How do I use $Push in MongoDB?

If the field is absent in the document to update, $push adds the array field with the value as its element. If the field is not an array, the operation will fail. If the value is an array, $push appends the whole array as a single element. To add each element of the value separately, use the $each modifier with $push .

How do I filter elements in MongoDB?

Filter MongoDB Array Element Using $Filter Operator This operator uses three variables: input – This represents the array that we want to extract. cond – This represents the set of conditions that must be met. as – This optional field contains a name for the variable that represent each element of the input array.


2 Answers

You need to use new: true to get the updated value and cast id to mongoose objectId to make it work

Post.findOneAndUpdate(
   { 'posts.replies._id': _id }, 
   { $set: { 'posts.$[post].replies.$[reply].text': "something1" } },
   { arrayFilters: [{ 'post._id': postId }, { 'reply._id': _id }], new: true }
)
like image 126
Ashh Avatar answered Sep 19 '22 00:09

Ashh


As arrayFilters are something related to mongodb, you need to cast id in mongoose with ObjectId

Post.findOneAndUpdate(
   { 'posts.replies._id': _id }, 
   { $set: { 'posts.$[post].replies.$[reply].text': "something1" } },
   { arrayFilters: [{ 'post._id': postId }, { 'reply._id': _id }]}
)

must be changed to

Post.findOneAndUpdate(
   { 'posts.replies._id': _id }, 
   { $set: { 'posts.$[post].replies.$[reply].text': "something1" } },
   { arrayFilters: [{ 'post._id': ObjectId(postId) }, { 'reply._id': ObjectId(_id)}]}
)
like image 23
Kodanda Rama Durgarao poluri Avatar answered Sep 18 '22 00:09

Kodanda Rama Durgarao poluri