0

I am trying to update single object inside an array that exist inside another array (nested array) but what happen that all records are removed and the new records are inserted instead this is the structure I am using:

"summary_mark" : [
    {
        "target_id" : "5aa27e77967c552b10ea725b", 
        "primitives" : [
            {
                "primitive" : "B", 
                "test_count" : NumberInt(3), 
                "right_test_count" : NumberInt(3), 
                "mark" : NumberInt(66)
            }, 
            {
                "primitive" : "T", 
                "test_count" : NumberInt(3), 
                "right_test_count" : NumberInt(3), 
                "mark" : NumberInt(66)
            }, 
            {
                "primitive" : "H", 
                "test_count" : NumberInt(3), 
                "right_test_count" : NumberInt(3), 
                "mark" : NumberInt(66)
            }
        ]
    }
], 

what i am trying to do is changing one of the records inside the primitives array.

actually i am trying to update the record using this function:

$testCount = ++$primitiveSummaryMark['test_count'];
        $update['summary_mark.$.primitives'][$primKey]['primitive'] = $answer->primitive_value;
        $update['summary_mark.$.primitives'][$primKey]['test_count'] = $testCount;

        if ($answer->result != 0) {
            $rightAnswersCount = ++$primitiveSummaryMark['right_test_count'];
            $update['summary_mark.$.primitives'][$primKey]['right_test_count'] = $rightAnswersCount;
        } else {
            $rightAnswersCount = $primitiveSummaryMark['right_test_count'];
        }

        if ($testCount < $level_tests_amount->tests_count[$target_level]) {
            $totalTestCount = $level_tests_amount->tests_count[$target_level];
        } else {
            $totalTestCount = $testCount;
        }

        $primitiveTargetMark = ($rightAnswersCount * 100) / $totalTestCount;
        $update['summary_mark.$.primitives'][$primKey]['mark'] = $primitiveTargetMark;

where I am performing some logic then run this query:

MyClass::raw()
        ->findOneAndUpdate([
            'course' => $this->first()->course,
            'summary_mark.target_id' => $data->target_id,
        ],
            ['$set' => $update]);

the input is something like this:

{"data":{ "target_id":"5aa27e77967c552b10ea725b","question":"5aa141b6c8af28381079e9c7", "answers":[{"primitive_value":"B","result":1,"elpassed_time":20,"distructor":""},{"primitive_value":"T","result":1,"elpassed_time":3,"distructor":""}]}}

what I expect to see is the records with primitives (B,T,H) but i get (B,T) cause those which they are updated i cause of the input

Cœur
  • 37,241
  • 25
  • 195
  • 267

2 Answers2

0

Old thread but took me a couple of days to figure this out. So posting what worked for me.

Mongo Object this is built for.

{
    "_id" : ObjectId("61965a0507254c65d472a905"),
    "name" : "Menu",
    "storeId" : "61965a0507254c65d472a902",
    "items" : [ 
        {
            "_id" : "61965a0507254c65d472a903",
            "link" : "home",
            "title" : "Home",
            "isPage" : true,
            "children" : []
        }, 
        {
            "_id" : "61965a1807254c65d472a907",
            "link" : "test-slug-changed",
            "title" : "Test Slug",
            "isPage" : true,
            "children" : []
        }
    ]
}

Use Case: Search for a document by $StoreId, from the found document find and update all items with _id matching the given $id.

Solution Using db.collection.updateMany() in laravel-mongodb.

  • First an array with filter conditions.
  • Second an array that uses mongo's $set operator and uses an iterator i produced by the arrayFilters
  • Third an array filter that allows you to traverse through the nested array and filter elements to update. This also exposes i as an positional variable to $set the selected element for update.
Menus::raw()->updateMany(
   array ('storeId' => $data->storeId),
   [ '$set' => ["items.$[i].link" => $request->get("seo")['slug']] ],
   array( 'arrayFilters' => [ array ('i._id' => $id)] )
);
0

If you are using the https://github.com/jenssegers/laravel-mongodb in this case you have to use this e.x:

Model::where('uuid','=',$request->get('uuid'))
        ->where('nestedObject.id','=',$request->get('id'))->update(['nestedObject.$.fieldName'=>"newDate"]);

*the sign $ operator will update the specific nested object in your array. Reference: Jessengers issues