簡體   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