在yiimongodbsuite中嵌入嵌入文档

时间:2013-07-20 07:48:57

标签: php mongodb yii-extensions yii

我需要在yiimongodbsuite中执行upsert命令。 我试过了

$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 );

但这显示错误。

Murls模型定义如下

   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建模为

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'的特定组合的记录,则只会更新评论数组。如果不存在,则会插入新记录

2 个答案:

答案 0 :(得分:3)

你是从错误的班级继承的。要保存文档,您必须从EMongoDocument而不是EMongoEmbeddedDocument继承。这些类很相似,但目的不同。

  • EMongoEmbeddedDocument仅适用于嵌入式文档,仅适用于嵌入式文档
  • EMongoDocumentEMongoEmbeddedDocument扩展到实际将数据保存到db的方法。

对于一系列评论,您有两种选择:

  1. 使用普通的php数组 - 简单的可操作性更低,功耗更低,容易出错...
  2. 使用array of embedded documents - 每个评论都是文档,因此可以验证,具有严格的结构等。
  3. 默认情况下,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有自动保存功能:)

答案 1 :(得分:1)

最后我以这种方式得到了解决方案:

       $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);
      }