在ODM上还原包含嵌入文档的文档

时间:2013-09-13 03:11:58

标签: php mongodb json doctrine-odm

以下是我的两个示例类:

/** @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;
  }
}

在我的代码中,我创建了一个Product实例,然后一些进程在$product->attributes上创建了一个Attribute实例数组。 我使用Doctrine ODM将没有问题的Product实例持久存储到mongoDB中。 我可以进入数据库(使用rockmongo),我看到了预先存在的文档,以及JSON视图上注释到attributes数组的类:

"_doctrine_class_name": "\Attribute"

但是当我使用QueryBuilder查询该产品时,我没有获取一个Attribute实例数组,而是获得了PersistentCollection(在运行时使用调试器查看isntance)。

我认为这与延迟加载有关,但它会破坏我的代码。 当我尝试调用json_encode($product)时,而不是级联到每个Attribtue实例,它只返回一个空数组。

以下是我希望从json_encode()获得的内容:

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

有没有办法禁用延迟加载,或者强制每个Attribute实例的正确实例化? 或者任何其他方式能够获得所需的JSON对象,而无需手动遍历整个结构? 谢谢!

1 个答案:

答案 0 :(得分:2)

我最终是如何解决延迟加载的问题:

// 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;
}

这会强制PersistentCollection对象逐个吐出适当的实例,然后jsonSerializable方法会很好地响应。

丑陋的IMO,但解决了这个问题。遗憾的是,您必须将此应用于您拥有的每个嵌入对象依赖项。

它有帮助!