2016-06-29 15 views
1

教義ODMで参照IDの配列を取得します。私は、ユーザーへの参照が会社に存在するかどうかをチェックし、への唯一の参照を保持する必要が私のコントローラで私は、ユーザーを参照Companyクラス持っ

/** 
* @MongoDB\Document() 
*/ 
class Company { 

    /* ... */ 

    /** 
    * @MongoDB\ReferenceMany(targetDocument="Topboard\UserBundle\Document\User", inversedBy="companies") 
    */ 
    protected $users; 
} 

をそのユーザーは、他の参照ではありません。私はまた、複数のDB要求をユーザに与えたくない。参照のIDが$currentUserIdと一致するかどうかを確認したいだけです。調査の際

public function getCompanyAction($companyId, $currentUserId) { 
    $dm = $this->get('doctrine_mongodb')->getManager(); 
    $company = $dm->getRepository('TopboardAppBundle:Company')->findOneById($companyId); 

    foreach ($company->getUsers() as $user) { 
     // Foreach will query each user separetly. This is not what I need. 
     // I need somehow access array of references' ids 
     // and compare them with the $currentUserId 
     if($user->getId() !== $currentUserId){ 
      // Remove reference 
     }   
    } 

    return $company; 

} 

答えて

1

それは収集が(私たちはより良いまだthis comment on GHを見ることができない理由を推論するために)、後に文書ごとにクエリを回避するために初期化されるときに、クエリが発射されることが判明しました。場合は、しかし失われていない解決策はどこにも美しいものの近くにはありませんが、パフォーマンスが最初に来る必要があるときに時々OD/RMにこれらを必要としている。

$users = $company->getUsers(); 
// condition below assumes $company is loaded from db so $users is in fact instance of PersistentCollection(Interface) 
if ($users->isInitialized()) { 
    $ids = $users->map(function($user) { 
     return $user->getId(); 
    })->toArray(); 
} else { 
    $ids = array_map(function($dbRef) { 
     /* this depends on reference type */ 
     return (string) $dbRef['$id']; 
    }, $users->getMongoData()); 
} 

あなたはまた、単に私がマッピングだ場所であなたのロジックを置くことができコレクションを参照して、参照ユーザーのIDのリストを取得します。オブジェクトがまだロードされていない場合は、単一の参照やunitinitailzedプロキシ

に関連する

オリジナルの答え(すなわち、それはまだProxy初期化されていない)、その文書の識別子を求めることは、追加のクエリをトリガしませんが、ここでスニペットがあります私のプロジェクトでODMによって生成Proxyクラスで:

public function getId() 
{ 
    if ($this->__isInitialized__ === false) { 
     return parent::getId(); 
    } 


    $this->__initializer__ && $this->__initializer__->__invoke($this, 'getId', []); 

    return parent::getId(); 
} 
また

ビットに答える展開し、あなたがprimingとN + 1つの問題を防ぐことができ、このようにODMはすべてREFEを取得します1つのクエリでドキュメントを更新しました。

+0

右のようなプロポーション音。では、UserクラスのIDゲッターを変更することをお勧めしますか?問題は、私が 'foreach'を実行すると、既にDBリクエストを引き起こすということです。 – Websirnik

+0

いいえ、あなたのゲッターはそのまま残すべきです、自動生成されたプロキシクラスをチェックすることができます(通常は 'app/cache/lcl/doctrine/odm/mongodb/Proxies /'にあります)。 'foreach'に関しては、あなたの参照が最初のフェッチの後に文書内ですでに利用可能な所有側であるため、それ自身でクエリを起動すべきではありません。 – malarzm

+0

私の場合、あなたのコードは正しいと思われ、この時点で追加のクエリを引き起こすべきではありません – malarzm

関連する問題