【问题标题】:Restore document with embedded documents on ODM使用 ODM 上的嵌入文档恢复文档
【发布时间】:2013-09-17 15:09:51
【问题描述】:

这是我有的两个示例类:

/** @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),我看到了presisted文档,以及attributes数组类的JSON视图上的注释:

"_doctrine_class_name": "\Attribute"

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

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

这是我期望从 json_encode() 获得的内容:

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

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

【问题讨论】:

  • 不使用 Doctrine ODM 而只使用原始 php Mongo 怎么样?
  • 嗯...解决问题的方法不多,因为要实现同质化,我需要重组项目。但是原始 php Mongo 是什么意思,我在哪里可以阅读一些教程或文档(在 ZF2 中具体)?
  • 我同意,这不是解决方案。但是 IMO 您正在尝试使用 ODM 功能来处理一种动态数组。如果我是对的,这对于\MongoClient\MongoCollection 来说很简单,因为您直接使用数组。您可以像$documentManager->getConnection()->getMongo() 这样通过教义-odm 访问它。不确定是否有帮助。

标签: php mongodb json doctrine-odm


【解决方案1】:

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

// 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,但解决了问题。可悲的是,您必须将其应用于您拥有的每个嵌入式对象依赖项。

有帮助!

【讨论】:

  • 老兄,我正在寻找那个解决方案!但我不明白的是:ODM 让我们做那种丑陋的事情的意图是什么?我们做错了吗?它应该如何正确?
  • 另一个更干净的解决方案是使用 $o->attributes = $this->attributes->toArray() 而不是手动 for 循环。但总觉得难看。
猜你喜欢
  • 1970-01-01
  • 2012-06-11
  • 2012-12-20
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多