我使用条令ODM来处理MongoDB。我有一些文件要保存,这些文件可能会不时重复。我只需要每个事件的一个副本,所以我使用散列的uniq键来确保事件只有1。
所以我做了几个->persistent($document);当我这样做的时候->flush();
我遇到了一个例外:localhost:27017:E11000重复密钥错误索引:dbname.event.$eventKey_1重复密钥:{:"keyValue"}
而且所有的数据从未持久化到MongoDB。所以问题是:是否有任何方法可以持久化uniq数据并忽略现有数据而不进行操作:
try {
->persist();
->flush();
} catch ('Exception $e) {}
对于每个文档?
谢谢。
更新:谢谢你的回答和时间,但我找到了确切的解决方案:)
Mongo函数插入有一个选项"ordered:"https://docs.mongodb.org/manual/reference/method/db.collection.insert/其允许即使在出现错误之后也继续插入。
教义使用Pecl扩展mongo。条令flush()使用此方法:http://www.php.net/manual/en/mongocollection.batchinsert.php具有选项"continueError"
所以如果你这样做:
$documentManager->flush(null, ['continueOnError' => true]);
它将保存所有没有错误的文档,并跳过所有有错误的文档。尽管它会抛出"''MongoDuplicateKeyException"。因此,您所需要的就是捕获此异常并处理或忽略它(取决于您的需要)。
如下所示:)
原生Doctrine方法不支持过滤唯一值-您需要自己完成。要在没有任何错误的情况下插入这些数据,您必须根据您的实体结构做一些事情:
-
使用您拥有的唯一密钥查找所有现有实体
-
查找在试图持久化的实体之间重复的唯一密钥
-
用您找到的实体替换现有实体
-
持久并刷新
如果没有至少一个额外的查询,就绝对没有机会做到这一点。如果您拥有现有实体的主键,则可以使用这些主键来获取引用对象。但不幸的是,根据条令文件,没有人支持通过唯一密钥获得参考:
http://doctrine-orm.readthedocs.org/en/latest/reference/limitations-and-known-issues.html#join-具有非主键的列
不能使用指向非主键的联接列。Doctrine会认为这些是主键,并使用数据创建懒惰加载代理,这可能会导致意想不到的结果。由于性能原因,条令不能在运行时验证此设置的正确性,只能通过validate Schema命令进行验证。
我无法使['continueOnError' => true]
工作,因此以不同的方式解决:
$collection = $documentManager->getDocumentCollection(Content::class);
try {
$collection->insertMany($arrayData, ['ordered' => false]);
} catch (BulkWriteException $exception) {
// ignore duplicate key errors
if (false === strpos($exception->getMessage(), 'E11000 duplicate key error')) {
throw $exception;
}
}
您只需执行以下操作:搜索现有id,编辑并保存。。
-
使用条令+符号:
$Document = $EntityManager->getRepository("ExpBundle:Document")->find(123); $Document->setTitile("Doc"); $EntityManager->flush();
-
使用条令
$Document = $EntityManager->find('Document', 1234); $Document->setTitle("edited"); $EntityManager->flush();