laravelmongodbdata-consistency

why this code works and eloquent create the subdocument if it is not exists?


suppose I have a collection with name ParrentObj and a corresponding Eloquent class named ParrentObj:

[//ParentObj eloquent objects
{
    "_id":ObjectId("5e11ae242cb48f79afcd4b07"),
    "Code":"a"
    "Children":[
        //children eloquent objects
        {
            "Code":"a-a",
            "GrandChildren":[
                //GrandChildren eloquent objects
                {
                    "Code":"a-a-a"
                },
                {
                    "Code":"a-a-b"
                }
            ]           
        },
        {
            "Code":"a-b",
            "GrandChildren":[
            ]           
        }
    ],
},
{
    "_id":ObjectId("5e11b125e1f94bccca6784e9"),
    "Code":"b"
    "Children":[
    ]
}]

I amazed how this line of code works properly because all evidence shows against it:

$result = ParrentObj::find('5e11ae242cb48f79afcd4b07')->where('Children.Code', 'a-a')
                                              ->whereNotIn('Children.GrandChildren.Code',['a-a-a'])
                                              ->push('Children.$.GrandChildren', $arr);//results: no effect on db
$result = ParrentObj::find('5e11ae242cb48f79afcd4b07')->where('Children.Code', 'a-a')
                                              ->whereNotIn('Children.GrandChildren.Code',['a-a-c'])
                                              ->push('Children.$.GrandChildren', $arr);//results:add a GrandChildren subdocument under the a-a Children

"ParrenObj" is an Eloquent Object that has a embedsMany relation On the Children field.

"Children" is also an eloquent object that has an "embeds many" relation on the GrandChildren field. (to 0 or n "GrandChildren" eloquent object(s))

as I know the result of the find is an eloquent or collection and with combination with where the result will be a query builder. when I try to get the result of this:

$result = ParrentObj::find($id)->where('Children.Code', "a-a")->first()

the result was a ParrentObj (eloquent object). and as I anticipate the Children field has two members (not one). How eloquent determine that ->push('Children.$.GrandChildren', $arr); should be applied on which Children?


Solution

  • It does not work for this case:

    $result = ParrentObj::find('5e11ae242cb48f79afcd4b07')->where('Children.Code', 'a-b')
                                              ->whereNotIn('Children.GrandChildren.Code',['a-a-a'])
                                              ->push('Children.$.GrandChildren', $arr);
    

    expected results:

    add a GrandChildren with code a-a-a subdocument under the a-b Children

    actual result:

    does not add any GrandChildren under a-b because whereNotIn matched a GrandChildren with same Code but in different Children