Уплотнение встроенного документа в yiimongodbsuite

Мне нужно выполнить команду upsert в yiimongodbsuite. Я пытался

$model = new Murls(); $model->userid=$userid; $model->title=$title; $model->edits[0] = new Medithtml(); $model->edits[0]->path= $htm; $model->edits[0]->html=$path; $model->edits[0]->ci=$ci; $model->update(array('_id'=>$rec->_id ),array('userid', 'title','edits' ), true ); 

Но это показывает ошибку.

Модель Мурлса определяется следующим образом

  class Murls extends EMongoDocument { public $userid; public $title; public $edits; public static function model($className=__CLASS__) { return parent::model($className); } // This method is required! public function getCollectionName() { return 'murls'; } public function attributeLabels() { return array( 'html'=>'Html', ); } public function embeddedDocuments() { return array( // property name => embedded document class name 'edits'=>'Medithtml', ); } public function behaviors(){ return array( 'embeddedArrays' => array( 'class' => 'ext.YiiMongoDbSuite.extra.EEmbeddedArraysBehavior', 'arrayPropertyName' => 'edits', // name of property, that will be used as an array 'arrayDocClassName' => 'Medithtml' // class name of embedded documents in array ), ); } } 

и модель Medithtml as

 class Medithtml extends EMongoEmbeddedDocument{ public $html; public $path; public $ci; public static function model($className=__CLASS__) { return parent::model($className); } } 

Я должен достигнуть того, что запись с $title может иметь n число $html , $path и $ci . Любая помощь будет оценена. Я ищу, чтобы хранить данные, подобные этому

  array ( '_id' => MongoId::__set_state(array( '$id' => '51ee1956d39c2c7e078d80da', )), 'userid' => '12', 'title' => 'Mongo', 'edits' => array ( 0 => array ( 'html' => 'html>body>div:nth-child(2)>a>div>a>div', 'path' => 'ssssss', 'ci' => '1', ), 1 => array ( 'html' => 'html>body>div:nth-child(2)>a>div:nth-child(3)>a>h2', 'path' => '/assets/img/demo/demo-avatar9604.jpg', 'ci' => '2', ), 2 => array ( 'html' => ' html>body>div:nth-child(2)>a>div:nth-child(3)>a>center:nth-child(16)>a>h1', 'path' => '333', 'ci' => '3', ), ), ) 

Только массив комментариев будет обновлен, если существует запись с определенной комбинацией 'title' и 'userid' Если она не существует, будет добавлена ​​новая запись

Вы наследуете от неправильного класса. Чтобы сохранить документ, вы должны наследовать EMongoDocument не EMongoEmbeddedDocument . Эти классы схожи, но имеют разные цели.

  • EMongoEmbeddedDocument для встроенных документов, он должен использоваться только для встроенных документов
  • EMongoDocument выходит из EMongoEmbeddedDocument с помощью методов фактического сохранения данных в db.

Для массива комментариев у вас есть два варианта:

  1. Используйте простой php-массив – простую, менее управляемую, меньшую мощность, erron prone ..
  2. Используйте массив встроенных документов – каждый комментарий является документом, поэтому его можно проверить, иметь жесткую структуру и т. Д.

По умолчанию save / insert / update сохраняет все атрибуты. Для частичных обновлений используйте комбинацию $attributes и установите $modify для true. Предупреждение . Передача массива атрибутов без $modify сохраняет только прошедшие атрибуты, отбрасывая остальную часть документа.

 public function save($runValidation = true, $attributes = null) ... public function insert(array $attributes = null) ... public function update(array $attributes = null, $modify = false) ... 

Так что в вашем случае вы можете обновить:

 $model->update(array('comments'), true); 

Или, если вам все овервердировать весь документ, просто сохраните:

 $model->save(); 

Примечание: для составного pk ovverride primaryKey() :

 public function primaryKey() { return array('title', 'userid'); } 

Хорошо, что stackoverflow имеет сквозную автосохранение черт 🙂

Наконец, я получил решение таким образом:

  $rec = $model->find($criteria) ; if($rec){ foreach($rec->edits as $editarray){ $var[]=$editarray; } $edits_new= new Medithtml(); $edits_new['html']=$htm; $edits_new['ci']=$ci; $edits_new['path']=$path; $var[]=$edits_new; $rec->edits=$var; $rec->userid=$userid; $rec->title=$title; $rec->update(array('edits' ), true); }