Laravel-mongodb: update nested child elements

Created on 24 Nov 2014  路  10Comments  路  Source: jenssegers/laravel-mongodb

I have a document with child elements of items like so

"bar" : "547244fe10f0edd3128b4567",
    "items" : [ 
        {
            "1" : {
                "message" : "",
                "display" : "true",
                "type" : "text"
            }
        }, 
        {
            "2" : {
                "id" : "234234",
                "type" : "image",
                "message" : "foo",
                "display" : "true",
                "created_at" : NumberLong(1416432114)
            }
        }, 
        {
            "3" : {
                "message" : "",
                "display" : "true",
                "type" : "text"
            }
        }, 

and I'm trying to update one of the childrens value

$foo['items']['1']['message'] = 'hello';
$story = InfoDB::where('_id', $id)->update($foo);

So that

            "1" : {
                "message" : "",
                "display" : "true",
                "type" : "text"
            }

Becomes

            "1" : {
                "message" : "hello",
                "display" : "true",
                "type" : "text"
            }

But when I run the update command it deletes all the children in the document.

Do I have to update the entire document? or is there another function?

Thanks

Most helpful comment

You have to use the specific MongoDB dot syntax : http://docs.mongodb.org/manual/reference/operator/update/set/#set-fields-in-embedded-documents.

In Laravel, it should be like that :

$story = InfoDB::where('_id', $id)->update(array('items.1.message' => $foo));

All 10 comments

You have to use the specific MongoDB dot syntax : http://docs.mongodb.org/manual/reference/operator/update/set/#set-fields-in-embedded-documents.

In Laravel, it should be like that :

$story = InfoDB::where('_id', $id)->update(array('items.1.message' => $foo));

Thanks :)

Thanks @alexandre-butynski

How to find index so i can apply that query with index @alexandre-butynski

@alexandre-butynski Thank you so much, your answer is useful, even after 3 years!

what if we don't know the index instead we have id in child doc

@navneetccna if you are using raw query than

https://docs.mongodb.com/manual/reference/operator/update/positional/#up._S_

else

you have to loop it your array and do something like this

foreach ($post->comments as $key => $comments) {
          if ($comments['id'] === $commentId) {
                  $id = $post->update(["comments.$key.comments" => [$data]], ['upsert' => true]);
          }
}

@prafful-panwar I don't think looping is the right solution. There is already $ operator available in mongo but how we can use in this library.

@prafful-panwar I don't think looping is the right solution. There is already $ operator available in mongo but how we can use in this library.

Is this is your question? Here in this snippet, old coupon's(>24Hr) state setting as Expired.

$yesterdaySameTime = Carbon::now()->subHours(24)->format('Y-m-d\TH:i:s');
$yesterdaySameTime = new \DateTime($yesterdaySameTime);

$couponUsage = CouponUsage::query()
      ->where('customer_id', 53)
      ->whereNotIn('data.usage.state', ['Consumed', 'Expired'])
      ->where('data.usage.time', '<', $yesterdaySameTime)
      ->update([
        'data.usage.$.state' => 'Expired'
      ]);

@prafful-panwar I don't think looping is the right solution. There is already $ operator available in mongo but how we can use in this library.

Is this is your question? Here in this snippet, old coupon's(>24Hr) state setting as Expired.

$yesterdaySameTime = Carbon::now()->subHours(24)->format('Y-m-d\TH:i:s');
$yesterdaySameTime = new \DateTime($yesterdaySameTime);

$couponUsage = CouponUsage::query()
      ->where('customer_id', 53)
      ->whereNotIn('data.usage.state', ['Consumed', 'Expired'])
      ->where('data.usage.time', '<', $yesterdaySameTime)
      ->update([
        'data.usage.$.state' => 'Expired'
      ]);

I know this thread is too old but still relevant to me. This query is updating first element only in the array.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bastiendonjon picture bastiendonjon  路  3Comments

kschethan picture kschethan  路  3Comments

imrannazirbhat picture imrannazirbhat  路  3Comments

yupangestu picture yupangestu  路  3Comments

phuocduy1988 picture phuocduy1988  路  3Comments