简体   繁体   English

在ODM上还原带有嵌入式文档的文档

[英]Restore document with embedded documents on ODM

Here are two sample classes I have: 这里有两个示例类:

/** @ODM\Document */
class Product implements JsonSerializable{

  /** @ODM\String */
  protected $some_property;

  /** @ODM\EmbedMany */
  protected $attributes;

  public function jsonSerialize(){
    $o = new StdClass();
    $o->property = $this->some_property;
    $o->attributes = $this->attributes;
    return $o;
  }
}

/** @ODM\EmbeddedDocument */
class Attribute implements JsonSerializable{

  /** @ODM\String */
  protected $some_property;

  public function jsonSerialize(){
    $o = new StdClass();
    $o->property = $this->some_property;
    return $o;
  }
}

In my code, I create an instance of Product, and then some processes create an array of Attribute instances on $product->attributes . 在我的代码中,我创建一个Product实例,然后一些进程在$product->attributes上创建Attribute实例数组。 I persist the Product instance without a problem into mongoDB using Doctrine ODM. 我使用Doctrine ODM将Product实例持久地存入mongoDB中。 I can go into the DB (using rockmongo), and I see the presisted document, and the annotations on the JSON view to the class of the attributes array: 我可以进入数据库(使用rockmongo),然后看到已有的文档以及JSON视图上对attributes数组类的注释:

"_doctrine_class_name": "\Attribute"

But when I query for that product using the QueryBuilder, instead of getting an array of Attribute instances, I get a PersistentCollection (looking at the isntance with the debugger at runtime). 但是,当我使用QueryBuilder查询该产品时,我没有获得Attribute实例数组,而是得到了PersistentCollection(在运行时查看调试器的外观)。

I believe this has to do with lazy loading , but its breaking up my code. 我相信这与延迟加载有关 ,但它破坏了我的代码。 When I try to call json_encode($product) , instead of cascading through to each of the Attribtue instances, it just returns an empty array. 当我尝试调用json_encode($product) ,而不是级联到每个Attribtue实例,它只是返回一个空数组。

Here is what I expect to get form a json_encode(): 这是我期望从json_encode()获得的内容:

{
    "property": "some product value",
    "attributes": [
        {
            "property": "some attribute value"
        },
        {
            "property": "some attribute value"
        }
    ]
}

Is there any way to either disable lazy loading , or force the proper instantiation of each Attribute instance? 有什么方法可以禁用延迟加载 ,或强制每个Attribute实例正确地实例化吗? Or any other way to be able to get the desired JSON object, without having to manually traversing the whole structure? 还是通过其他任何方式都可以获取所需的JSON对象,而不必手动遍历整个结构? Thanks! 谢谢!

How I ended up solving the issue of lazy-loading: 我如何最终解决延迟加载的问题:

// parent jsonSerialize method
public function jsonSerialize(){
  $o = new StdClass();
  $o->property = $this->some_property;
  $a = [];
  foreach($this->attributes as $attr){
    $a[] = $attr;
  }
  $o->attributes = $a;
  return $o;
}

This forces the PersistentCollection object to spit our one by one the proper instances, and then the jsonSerializable methods respond well cascaded through. 这迫使PersistentCollection对象将适当的实例一一吐出来,然后jsonSerializable方法可以很好地级联响应。

Ugly IMO, but solves the issue. IMO丑陋,但解决了这个问题。 Sadly, you have to apply this on every Embedded Object dependency you have. 可悲的是,您必须将此方法应用于您拥有的每个嵌入式对象依赖项。

Hole it helps! 孔有帮助!

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

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