製品を含むいくつかのカテゴリがありますが、カテゴリに製品を追加できます。これは多対多の関係ですが、製品はカテゴリとの関係を認識していません (カテゴリ内にのみ保存されるため)。最初に設定を投稿し、次に問題を引き起こすクエリを投稿します。
/** @ODM\Document */
class Category
{
/** @ODM\Id */
private $id;
/** @ODM\String */
private $name;
/** @ODM\ReferenceMany(targetDocument="Product", inversedBy="category") */
private $products;
public function setProducts($products)
{
$this->products = $products;
}
}
/** @ODM\Document */
class Product
{
/** @ODM\Id */
private $id;
/** @ODM\String */
private $name;
/** @ODM\Float */
private $price;
/** @ODM\ReferenceMany(targetDocument="Category", mappedBy="products") */
private $category;
}
いくつかのデータを用意するために、次のように作成します。
$p1 = new Documents\Product();
$p1->setName('p1');
$p1->setPrice(1.99);
$p2 = new Documents\Product();
$p2->setName('p2');
$p2->setPrice(3.99);
$c1 = new Documents\Category();
$c1->setName('category1');
$c1->setProducts(array($p1, $p2));
$c2 = new Documents\Category();
$c2->setName('category2');
$c2->setProducts(array($p1, $p2));
$dm->persist($p1);
$dm->persist($p2);
$dm->persist($c1);
$dm->persist($c2);
$dm->flush();
MongoDB を調べたところ、次のデータが得られました。
db.Category.find()
{ "_id" : ObjectId("53e3d8d3e2afec2303d63afa"), "name" : "category1", "products" : [ DBRef("Product", ObjectId("53e3d8d3e2afec2303d63af8")), DBRef("Product", ObjectId("53e3d8d3e2afec2303d63af9")) ] }
{ "_id" : ObjectId("53e3d8d3e2afec2303d63afb"), "name" : "category2", "products" : [ DBRef("Product", ObjectId("53e3d8d3e2afec2303d63af8")), DBRef("Product", ObjectId("53e3d8d3e2afec2303d63af9")) ] }
db.Product.find()
{ "_id" : ObjectId("53e3d8d3e2afec2303d63af8"), "name" : "p1", "price" : 1.99 }
{ "_id" : ObjectId("53e3d8d3e2afec2303d63af9"), "name" : "p2", "price" : 3.99 }
私は今、このデータを照会したいと思います: ID で製品を取得し、そのすべてのカテゴリを取得すると、次のものが属します:
$product = $dm->find('Documents\Product', '53e3d8d3e2afec2303d63af8');
var_export($product->getName());
$category = $product->getCategory();
var_export(sizeof($category));
foreach($category as $c){
var_export($c->getName());
}
// Outputs: 'p1' 2 'category1' 'category2'
しかし、逆の方法でデータをクエリしたい場合: カテゴリを取得し、そのすべての製品を取得すると、カテゴリには次のものが含まれます。
$category = $dm->find('Documents\Category', '53e3d8d3e2afec2303d63afa');
var_export($category->getName());
$products = $category->getProducts();
var_export(sizeof($products));
foreach($products as $p){
var_export($p->getName());
}
// Outputs: 'category1' 2
製品が表示されず、致命的なエラーが発生します:
Fatal error: Uncaught exception 'MongoCursorException' with message 'localhost:27017: Can't canonicalize query: BadValue $in needs an array' in /private/var/www/mongo/vendor/doctrine/mongodb/lib/Doctrine/MongoDB/Cursor.php on line 288
MongoDB ログを調べると、クエリは次のようになります。
assertion 17287 Can't canonicalize query: BadValue $in needs an array ns:shop.Product query:{ $query: { _id: { $in: { 53e3d8d3e2afec2303d63af8: ObjectId('53e3d8d3e2afec2303d63af8'), 53e3d8d3e2afec2303d63af9: ObjectId('53e3d8d3e2afec2303d63af9') } } }, $orderby: [] }
つまり、問題は明らかです$in
。配列が必要ですが、JSON 配列が指定されていません。しかし、私はそれを修復する方法がわかりません。私は何を間違っていますか?この特定の問題に答えられない場合は、このような多対多の関係があり、両側でデータをクエリできる Doctrine を使用した MongoDB の実際の例を教えてください。
更新:私が使用しているドクトリンのバージョンについて言及する必要があったかもしれません。私はこの設定を使用しました:
{
"require":{
"doctrine/common":"2.3.*",
"doctrine/dbal":"2.3.*",
"doctrine/orm":"*",
"doctrine/mongodb-odm": "1.0.0-BETA9"
}
}
次に、利用可能な最新バージョンに更新することを考え、次の設定を使用しました。
{
"require":{
"doctrine/common":"2.4.*",
"doctrine/dbal":"2.3.*",
"doctrine/orm":"*",
"doctrine/mongodb-odm": "dev-master"
}
}
そして出来上がり: すべて正常に動作します.... OMG. しかし、これについての説明は大歓迎です。ここで何が起こったのか知りたいです。どうもありがとう。