如何更新Doctrine MongoDB中的嵌入文档


How do I update embedded documents in Doctrine MongoDB?

我有一个嵌入了文档的文档。当我第一次创建对象时,一切都很好,但当我尝试更新文档时,嵌入的文档不会得到更新。

/** @MongoDB'Document */
class DocumentA
{
    /** @MongoDB'EmbedOne(targetDocument="DocumentB") **/
    protected $docB;
    /** @MongoDB'String */
    protected $valueA;
}
/** @MongoDB'EmbeddedDocument */
class DocumentB
{
    /** @MongoDB'String */
    protected $valueB;
}

在我的应用程序中,我查询文档,更新值并将它们持久化到数据存储中。

// Variant A – Does not work
$document = ... // find from data store
$document->setValueA('Hello World');
$document->getDocB()->setValueB('foo baz');
$om->persist($document);
$om->flush();

如果我不更新嵌入的文档,而是设置一个新的文档,一切都很好:

// Variant B - Does work
$document = ... // find from data store
$document->setValueB('Hello World 2');
$document->setDocB(new DocumentB());
$document->getDocB()->setValueB('foo baz 2');
$om->persist($document);
$om->flush();

正如我所说,变体B运行良好。然而,在我的应用程序中,文档更为复杂,每次更新嵌入文档时为其创建一个新对象对我来说是不切实际的。有没有一种方法可以告诉Doctrine ODM查看嵌入文档的值,以决定是否应该更新它?

我面临着完全相同的问题。事实证明,UnitOfWork在计算嵌入其他文档的文档变更集时似乎失败了,尽管我一直不知道为什么。。。因此,当我比较实际值和原始值时,工作单位显示两者的值相同。与您的变体A交谈时,当您

$document->getDocB()->setValueB('foo baz');

工作单元显示新旧值的"foo-baz",不会将其视为更改,因此不会更新。

无论如何,这是一个变通方法:

$document = ... // find from data store
$document->setValueA('Hello World');
$docB = $document->getDocB();
$docB->setValueB('foo baz');
$om->detach($docB);
$om->persist($document);
$om->flush();

这使得工作单元将$document的docB识别为新设置的文档,并将按预期刷新它。

MongoDB只有原子操作。您可以选择:1.查询文档,找到合适的子文档,更新整个文档或其部分。优点:逻辑简单缺点:非原子2.如果子文档在列表中,则使用位置$运算符。