如何在 symfony2 中使用子文档映射 mongo 文档

Posted

技术标签:

【中文标题】如何在 symfony2 中使用子文档映射 mongo 文档【英文标题】:How to map mongo documents with subdocuments in symfony2 【发布时间】:2013-09-25 21:59:31 【问题描述】:

我正在尝试创建 symfony2 应用程序,它将使用以下结构访问 mongoDB 集合:


  "_id": ObjectId("5239c1c0359bf908058a5071"),
  "param2": "test",
  "param3": 
       "subparam31": 0,
       "subparam32": 0,
       "subparam33": 0
   ,
   "param4": 1

在 symfony 2 中,我创建了一个 .yml 和 php 类。我只正确映射了“_id”、“param2”和“param4”,而不是“param3”的“subparam31”、“subparam32”和“subparam33”。

我使用下一个文件结构进行映射:

参数.mongodb.yml:

Acme\StoreBundle\Document\Params:
db: test 
type: document
fields:
    id:
        id:  true
    param2:
        type: string
    param3:
        type: mixed
    subparam31:
        type: float
    subparam32:
        type: float
    subparam33:
        type: float
    param4:
        type: float

参数.php

<?php
 namespace Acme\StoreBundle\Document;

class Params 

    protected $param2; 

    protected $param4;

    protected $param3;

    protected $subparam31;  

    protected $subparam32; 

    protected $subparam33;

?>

我哪里错了?如何获取和设置子参数的值?

为了访问 param2、param4 和 id,我在控制器中使用了以下代码:

$parameter = $this->get('doctrine_mongodb')
        ->getRepository('AcmeStoreBundle:Params')
        ->find($id);
    $parameter2 = $parameter->getParam2();
    $parameter4 = $parameter->getParam4();
    if (!$format) 
        throw $this->createNotFoundException('Not found parameter with id -> '.$id);
    
    return array(
    "parameter2" => $parameter2,
    "parameter4" => $parameter4
    ); 

我希望我已经足够清楚了。 提前致谢。

【问题讨论】:

【参考方案1】:

我找到了解决方案!除了 yml 中的映射,php 类中也需要定义相应的注解。

这里是必要文件的内容:

参数.mongodb.yml

Acme\StoreBundle\Document\Params:
db: test 
type: document
embedOne:
    param3: 
        targetDocument: Param3
fields:
    id:
        id:  true
    param2:
        type: string
    param4:
        type: float   

Param3.mongodb.yml

Acme\StoreBundle\Document\Param3:
db: test 
type: embeddedDocument
fields:
    subparam31:
        type: float
    subparam32:
        type: float
    subparam33:
        type: float      

参数.php

<?php

namespace Acme\StoreBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations;

/**
 * @Doctrine\ODM\MongoDB\Mapping\Annotations\Document
 */
class Params

/**
 * @Doctrine\ODM\MongoDB\Mapping\Annotations\Id
 */
protected $id;

/**
 * @Doctrine\ODM\MongoDB\Mapping\Annotations\String
 */
protected $param2;

/**
 * @Doctrine\ODM\MongoDB\Mapping\Annotations\Float
 */
protected $param4;

/**
 * @Doctrine\ODM\MongoDB\Mapping\Annotations\EmbedOne(targetDocument="Param3")
 */
protected $param3;

public function __construct($subparam31 = NULL, $subparam32 = NULL, $subparam33 = NULL)

    $param3 = new Param3($subparam31, $subparam32, $subparam33); 
    $this->setParam3($param3);


/**
 * Get id
 *
 * @return id $id
 */
public function getId()

    return $this->id;


/**
 * Set param2
 *
 * @param string $param2
 * @return self
 */
public function setParam2($param2)

    $this->param2 = $param2;
    return $this;


/**
 * Get param2
 *
 * @return string $param2
 */
public function getParam2()

    return $this->param2;


/**
 * Set param4
 *
 * @param float $param4
 * @return self
 */
public function setParam4($param4)

    $this->param4 = $param4;
    return $this;


/**
 * Get param4
 *
 * @return float $param4
 */
public function getParam4()

    return $this->param4;


/**
 * Set param3
 *
 * @param Acme\StoreBundle\Document\Param3 $param3
 * @return self
 */
public function setParam3(\Acme\StoreBundle\Document\Param3 $param3)

    $this->param3 = $param3;
    return $this;


/**
 * Get param3
 *
 * @return Acme\StoreBundle\Document\Param3 $param3
 */

public function getParam3($toArray = false)

    if ($toArray) 
        if ($this->param3) 
            return $this->param3->toArray();
        
    
    return $this->param3;

public function toArray()

    return array(
        'param3' => $this->getParam3(true)
    );

参数3.php

<?php

 namespace Acme\StoreBundle\Document;

 use Doctrine\ODM\MongoDB\Mapping\Annotations;

 /**
  * @Doctrine\ODM\MongoDB\Mapping\Annotations\EmbeddedDocument
  */
 class Param3
 
/**
 * @Doctrine\ODM\MongoDB\Mapping\Annotations\Float
 */
protected $subparam31;

/**
 * @Doctrine\ODM\MongoDB\Mapping\Annotations\Float
 */
protected $subparam32;

/**
 * @Doctrine\ODM\MongoDB\Mapping\Annotations\Float
 */
protected $subparam33; 

public function __construct($subparam31 = NULL, $subparam32 = NULL, $subparam33 = NULL)

    $this->subparam31 = $subparam31;
    $this->subparam32 = $subparam32;
$this->subparam33 = $subparam33; 



/**
 * Set subparam31
 *
 * @param float $subparam31
 * @return self
 */
public function setSubparam31($subparam31)

    $this->subparam31 = $subparam31;
    return $this;


/**
 * Get subparam31
 *
 * @return float $subparam31
 */
public function getSubparam31()

    return $this->subparam31;


/**
 * Set subparam32
 *
 * @param float $subparam32
 * @return self
 */
public function setSubparam32($subparam32)

    $this->subparam32 = $subparam32;
    return $subparam32;


/**
 * Get subparam32
 *
 * @return float $subparam32
 */
public function getSubparam32()

    return $this->subparam32;


/**
 * Set subparam33
 *
 * @param float $subparam33
 * @return self
 */
public function setSubparam33($subparam33)

    $this->subparam33 = $subparam33;
    return $this;


/**
 * Get subparam33
 *
 * @return float $subparam33
 */
public function getSubparam33()

    return $this->subparam33;


public function toArray()

    return array(
        'subparam31' => $this->getSubparam3(),
        'subparam32' => $this->getSubparam32(),
    'subparam33' => $this->getSubparam33()
    );

这个question 帮助了我。

【讨论】:

【参考方案2】:

我认为您正在寻找的是EmbeddedDocument。

param3(包括subparam31、subparam32 和subparam33)定义一个单独的文档,将其设置为params 中的targetDocument。所以Params.mongodb.yml 看起来像:

db: test 
type: document
embedOne:
  params3:
     targetDocument: params3Class
fields:
    id:
        id:  true
    param2:
        type: string
    param4:
        type: float

【讨论】:

好的,我如何在 symfony 中从控制器访问 subparam31、subparam32 和 subparam33 并获取和设置它们的值?我可以访问 id、param2 和 param4,但不能访问其他。我应该写什么代码? 您只需为 params 编写一个 getter 方法,让您可以访问 params3。所以它可能看起来像这样:$subparams31 = $params-&gt;getParams3()-&gt;getSubParam31() Getter 方法不起作用,我不知道为什么。当我按照您建议的方式使用它时,浏览器会出现白屏。 这可能是因为函数 $getParam3() 返回的不是对象,而是变量。为了生成 php 类,使用了以下命令:php app/console dictionary:mongodb:generate:documents AcmeStoreBundle。也许 symfony 没有执行适当的映射。 你是否定义了一个类来表示 params3 子文档,就像在 Doctrine 文档中的示例中一样?

以上是关于如何在 symfony2 中使用子文档映射 mongo 文档的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 项目中的 Doctrine2 映射问题

在 symfony2 中使用资产的源映射

在 Symfony2 中使用 Doctrine 映射异常错误

symfony2:如何在 QueryBuilder 中使用 group_concat

Symfony2 映射一对多多音

访问 Symfony2 控制器中未映射的字段