使用doctrine和mongodb更新数组中的嵌入子文档
我想更新(替换)所有文档数组中的一个子文档,其中包含此特定的嵌入子文档 我的样本内容对象是:使用doctrine和mongodb更新数组中的嵌入子文档,mongodb,doctrine,document,Mongodb,Doctrine,Document,我想更新(替换)所有文档数组中的一个子文档,其中包含此特定的嵌入子文档 我的样本内容对象是: { "_id" : ObjectId("51f289e5345f9d10090022ef"), "title" : "This is a content", "descriptors" : [ { "_id" : ObjectId("51f289e5345f9d10090022f4"), "name" : "Thi
{
"_id" : ObjectId("51f289e5345f9d10090022ef"),
"title" : "This is a content",
"descriptors" : [
{
"_id" : ObjectId("51f289e5345f9d10090022f4"),
"name" : "This is a descriptor",
"type" : "This is a property"
},
{
"_id" : ObjectId("51f289e5345f9d10090022f0"),
"name" : "This is another descriptor",
"type" : "This is another property"
}
]
}
我想找到具有特定描述符的对象。\u id
。
我想用另一个子文档替换一个子文档(分别使用旧对象的更新版本,但不一定具有相同的属性)
虽然这在/shell中运行良好
db.Content.update(
{
'descriptors._id': ObjectId("51f289e5345f9d10090022f4")
},
{
$set: {
'descriptors.$': {
"_id" : ObjectId("51f289e5345f9d10090022f4"),
"name" : "This is the updated descriptor",
"category" : "This is a new property"
}
}
},
{
'multi': true
})
…和
…它不适用于
…因为它失败并出现以下错误:
注意:C:\MyProject\vendor\doctrine\mongodb odm\lib\doctrine\odm\mongodb\Persisters\DocumentPersister.php第998行中未定义的偏移量:2
所以我假设MongoDB ODM原则需要点符号中的三个部分。不太好的解决方案是迭代子文档的属性并手动设置它们
$descriptor = array();
$descriptor['_id'] = new \MongoID('51f289e5345f9d10090022f4');
$descriptor['name'] = 'This is the updated descriptor';
$descriptor['category'] = 'This is a new property';
$query = $dm->createQueryBuilder('Content')
->update()->multiple(true)
->field('descriptors._id')->equals($descriptor['_id']);
foreach ($descriptor as $key => $value) {
$query->field('descriptors.$.'.$key)->set($value);
}
$query->getQuery()->execute();
但这只会更新现有的和添加新属性,但不会从子文档中删除旧的/不必要的属性
如何解决问题的任何想法:
- 通过一个简单的查询
- 在使用MongoDB ODM时
- 在php中不循环子文档数组
- Mongo服务器:2.4.5
- PHP:5.4.16
- PHP Mongo驱动程序:1.4.1
"php": ">=5.3.3",
"symfony/symfony": "2.3.*",
"doctrine/orm": ">=2.2.3,<2.4-dev",
"doctrine/doctrine-bundle": "1.2.*",
"doctrine/mongodb-odm": "1.0.*@dev",
"doctrine/mongodb-odm-bundle": "3.0.*@dev"
“php”:“>=5.3.3”,
“symfony/symfony”:“2.3.*”,
“条令/orm”:“>=2.2.3,这是ODM中的一个bug,应该在中修复。请查看并确保修改后的测试满足您的用例
在ODM的下一个测试版被标记之前,它将只驻留在主分支中;但是,这应该与您的1.0.*@dev
版本要求相匹配。您可以这样做,但“不容易”“当您在条令中使用Embeddemany或ReferenceMany时,方法成为一个对象,该对象使用$strict参数设置为true的方法来实现该方法(如所解释的)。。。这种方法适用于ReferenceMany,但不适用于Embeddemany
其概念是:ArrayCollection->array->ArrayCollection
在文档的定义中
$descriptor = array();
$descriptor['_id'] = new \MongoID('51f289e5345f9d10090022f4');
$descriptor['name'] = 'This is the updated descriptor';
$descriptor['category'] = 'This is a new property';
$query = $dm->createQueryBuilder('Content')
->update()->multiple(true)
->field('descriptors._id')->equals($descriptor['_id']);
foreach ($descriptor as $key => $value) {
$query->field('descriptors.$.'.$key)->set($value);
}
$query->getQuery()->execute();
"php": ">=5.3.3",
"symfony/symfony": "2.3.*",
"doctrine/orm": ">=2.2.3,<2.4-dev",
"doctrine/doctrine-bundle": "1.2.*",
"doctrine/mongodb-odm": "1.0.*@dev",
"doctrine/mongodb-odm-bundle": "3.0.*@dev"
/**
* @ODM\EmbedMany(targetDocument="EmbeddedElement")
*/
private $elements = array();
...
public function getElements() { return $this->elements; }
public function setElements($elements) { $this->elements = $elements; }
public function addElement(Element $element) { $this->elements[] = $element; }
public function setElement(Element $element, $index=0)
{
$elementsArray = $this->elements->toArray();
$elementsArray[$index] = $element;
$this->elements = new ArrayCollection($elementsArray);
}
public function removeElement(Element $element)
{
$index = array_search($element, $this->elements->toArray(), $strict=false);
if($index !== false)
$this->elements->remove($index);
}
public function removeElementByIndex($index) { $this->elements->remove($index); }