繁体   English   中英

从控制器添加对文档的引用,而无需事先查询数据库(Symfony / Doctrine MongoDB)

[英]Adding references to a Document from controller without previously querying the DB (Symfony/Doctrine MongoDB)

我已经搜索过StackOverflow,并阅读了Doctrine文档的相应章节( http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/index.html ),但是找不到我在寻找什么。

我正在使用Symctony v2.8制作的API,使用Doctrine MongoDB v1.1和MongoDB v3.0.14数据库。

我有两个不同的文档:“ Spot”和“ Feature”。 “ Spot”包含文档“ Feature”的集合,具有ReferenceMany关系:

// Spot document declaration

/**
 * @var \Transversal\SessionBundle\Document\Feature
 * @MongoDB\ReferenceMany(strategy="set", targetDocument="Transversal\SessionBundle\Document\Feature", sort={"uploadDate"="asc"})
 * @Serializer\Expose
 */
protected $features = array();

我正在使用Spot创建路线/控制器,在这里我需要发送Spot名称,描述以及要添加到Spot的现有功能的列表。

我现在要做的是在请求的正文中发送名称,描述和功能ID数组。 然后,在控制器中,我遍历此数组,并为每个id输入以下代码:

  • 通过其ID从数据库中获取功能的实例(因此每次迭代一个数据库请求)
  • 通过我的$spot->addFeature()方法将其添加到Spot对象

然后,我坚持并冲洗以保存新创建的位置。 这是我的控制器方法的代码(我修改了代码以使其更具可读性):

 * @Rest\Post("")
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   * @throws BosHttpException
   */
  public function createAction()
  {
    $spot = new Spot();
    $request = $this->getCurrentRequest();

    // retrieve the name and description for the new spot here
    $form = $this->createForm(SpotType::class, $spot);
    $form->handleRequest($request);

    $content = $request->getContent();
    $params = "";
    if (!empty($content)) {
      $params = json_decode($content, true);
    }

    $document_manager = $this->getDocumentManager();
    $featureIds = $params['featureIds'];
    foreach ($featuresIds as $featureId) {
      $feature = $document_manager->find('Transversal\SessionBundle\Document\Feature', $featureId);
      $spot->addFeature($feature);
    }

    $document_manager = $this->getDocumentManager();
    $document_manager->persist($spot);
    $document_manager->flush();

    return $this->getOutputView("Spot creation - succeed", Codes::HTTP_CREATED, $this->formatResponse(null, true));

  }

这是Spot.php文件中的addFeature()代码:

/**
 * Add feature
 *
 * @param \Transversal\SessionBundle\Document\Feature $feature
 */
public function addFeature(\Transversal\SessionBundle\Document\Feature $feature)
{
    $this->features[] = $feature;
}

这意味着如果我有一个包含20个Feature ID的数组,我的foreach循环将请求20倍的数据库,并且我知道这不是一个可行的解决方案(我知道我可能可以使用单个请求将其全部获得,但这不是我所需要的。正在寻找)。

有没有一种方法可以将功能分配给Spot,而无需生成它们的实例并在知道有引用的情况下请求我的数据库?

在此先感谢您的帮助!

这是如何使用@ParamConverter仅传递$ feature的ID而不传递对象的示例

use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;

/**
 * @ParamConverter("feature", class="YourBundle:Feature")
 */
public function addFeature(\Transversal\SessionBundle\Document\Feature $feature){
  $this->features[] = $feature;
}

这意味着如果让这样的代码

foreach($featuresIds as $featureId) {  
  $spot->addFeature($featureId);
}

也会起作用,因为主义应该认识到您作为参数传递的id是“功能”实体的id。 无论如何,ORM也在查询以获取对象,您可以尝试比较时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM