简体   繁体   English

MongoDB + Doctrine ODM如何删除文档集中的嵌入式文档?

[英]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. 我将MongoDB与Doctrine ORM结合使用,并希望在文档集合中删除嵌入的文档“头像”(或将其设置为null)。

My Json-Object looks like this: 我的Json-Object看起来像这样:

{
    "_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 我正在使用queryBuilder并尝试这样的事情

$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) 第3行:按ID获取父对象(不存储)
line 4: get the store by $key. 第4行:通过$ key获得商店。 Then i can use ->set(null) to set the embedded Object to null or to remove it with 然后我可以使用-> set(null)将嵌入的Object设置为null或使用

->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. 您可以在核心运算符中使用等效于$unset的示例。 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. 您只需保留实际需要的“存储”数组中元素的_id值即可,这有助于匹配将文档删除到的数组元素的位置。

Also using "dot notation" for the embedded document path. 还对嵌入式文档路径使用“点符号”

That "removes" the "key" from the document rather than just setting it to null . 这样可以从文档中“删除”“键”,而不仅仅是将其设置为null

If you want "mutiple" then you want .update() instead, but this does not return the object. 如果要“多个”,则需要.update() ,但这不会返回对象。


Ughh! gh!

To select things you just use: 要选择您只使用的东西:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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