简体   繁体   中英

MongoDB+Doctrine ODM How to remove a embedded document in a document collection?

im using mongoDB with Doctrine ORM and want to remove the embedded document "avatar" (or set it to null) in a document collection.

My Json-Object looks like this:

{
    "_id" : ObjectId("55965d090203ff700f000032"),
    "name" : "test",
    "stores" : [ 
        {
            "_id" : ObjectId("559d166f0203ff081300002f"),
            "storeName" : "test",
            "openingTimes" : "",
            "address" : {
                ...
            },
            "contactPerson" : {
                "firstname" : "",
                "lastname" : "",
                ...
                "avatar" : {
                    "source" : "/uploads/images/company/55965d0980585/contactPerson/",
                    "name" : "contactperson.jpg"
                }
            }
        }, 
...
    ]
}

Im using the queryBuilder and try something like this

$company = $this->getQueryBuilder()
                    ->findAndUpdate()
                    ->field('stores')->equals($store)
                    ->field('contactPerson.avatar')->set(null)
                    ->getQuery(array('multiple' => true))
                    ->execute();

But it does´t work. How can i get access to the avatar key?

I don´t know if it´s the best way but this one works for me

$company = $this->getQueryBuilder()
                    ->findAndUpdate()
                    ->field('_id')->equals($company->getId())
                    ->field('stores.'.$key.'.contactPerson.avatar')->set(null)
                    ->getQuery()
                    ->execute();

line 3: get the parent object by id (not store)
line 4: get the store by $key. Then i can use ->set(null) to set the embedded Object to null or to remove it with

->field('stores.'.$key.'.contactPerson.avatar')->unsetField()->exists(true)

@Blakes Seven: Thanks for your helpful answer :-)

You can use the equivalent of $unset in the core operators to do this example. Where I would actually suggest for brevity and safety to use:

$company = this->getQueryBuilder()
    ->findAndUpdate()
    ->field('stores._id')->equals($storeId)
    ->field('stores.$.contactPerson.avatar')->unsetField()->exists(true)
    ->getQuery()
    ->execute();

Where you just hold on to the _id value from the element in the "stores" array that you actually want and this helps match the position of the array element you need to remove that document to.

Also using "dot notation" for the embedded document path.

That "removes" the "key" from the document rather than just setting it to null .

If you want "mutiple" then you want .update() instead, but this does not return the object.


Ughh!

To select things you just use:

$company = this->getQueryBuilder()
    ->find()
    ->field('stores._id')->equals($storeId)
    ->select('stores.$.contactPerson.avatar')-
    ->getQuery()
    ->execute();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM