Php Doctrine2:如何处理缺失的关系文档
在一个巨大的数据集中,当一个文档被删除时,我有时会发现不一致。Symfony2应用程序,带条令ODM和FosRESTPhp Doctrine2:如何处理缺失的关系文档,php,mongodb,symfony,doctrine-orm,Php,Mongodb,Symfony,Doctrine Orm,在一个巨大的数据集中,当一个文档被删除时,我有时会发现不一致。Symfony2应用程序,带条令ODM和FosREST $a = new Element(); $b = new Element(); $c = new List(); $c->addElement($a); $c->addElement($b); $em->persist($c); 在这一点上储蓄是完美的 在99%的情况下,当稍后加载$c时,$a和$b仍然是有效的文档。 但是有时删除$a或$b而不更新$c中的引
$a = new Element();
$b = new Element();
$c = new List();
$c->addElement($a);
$c->addElement($b);
$em->persist($c);
在这一点上储蓄是完美的
在99%的情况下,当稍后加载$c时,$a和$b仍然是有效的文档。
但是有时删除$a或$b而不更新$c中的引用
->此时,下一次加载$c将失败,出现\doctor\ODM\MongoDB\DocumentNotFoundException
(消息类似于:找不到标识符为“541417702798711d2900607c”的“MongoDBODMProxies\uu_CG\u_\App\Model\Element”文档。)
现在处理这个案件的最佳方法是什么 我也在想
- 捕获异常并检查它试图加载的引用是否位于图元模型上
- fosRest中要检查的自定义异常处理程序
- 映射中的自定义存储库函数,并检查是否所有内容仍然有效(+以某种方式存储缺少的元素)->但这会迫使我在每次设置“错误”时都进行检查
更新:文档之间的映射比我在这里描述的要复杂一些
- 例如,元素基本上是一个由鉴别器分隔的集合,其中只有一种类型的字段引用另一个文档(我现在称之为“树”)
- 一棵树可以用于数千个ElementTree(包含树的特定类型)
- 有时可以删除树(这已经是一个运行缓慢的过程,因为那时需要更新大量数据)
- 现在,我需要找出哪些列表需要更改,并基本上拒绝对这些列表的api调用,其中包含特定元素不再可用的信息
$ app/console doctrine:mongodb:mapping:info
$ app/console doctrine:mongodb:cache:clear-metadata
目前有效的完美解决方案 我现在选择抛出一个新的异常(重要的是不要让条令抛出一个异常,因为它将拒绝同一请求中的任何持久化尝试) 在后加载生命周期事件中,我现在检查以下内容(简化):
在RestController中,这使我现在能够捕获此特定异常并从列表中删除无效元素+向用户返回一个自定义视图,指示该元素已被删除。所有点均有效->当前引用仅存储在列表中。(原因是列表中的条目几乎不会超过1-20个,但一个元素可以包含在数千个列表中)(…enter保存注释…)-现在,其他人仍可以编辑或删除元素。-即使我随后搜索包含特定元素的所有列表,我有时仍会遇到元素已被删除的列表中引用了一个元素的情况。(即使只有几毫秒…)因此,您不希望能够删除元素,或者在这样做时,您必须添加代码,同时删除所有相关列表文档中的引用。MongoDB是非关系型的,因此这意味着您必须自己(在代码中)处理关系逻辑
if ($document instanceof List) {
foreach ($document->getElements() as $element) {
// at this moment $element->getId() is already defined but not yet loaded from mongo
$result = $this->elementRepository->findBy(array(‘_id’ => $element->getId()));
if (sizeof($result)==0) {
throw new InvalidElementInList($element->getId());
}
}
}