2014-09-02 1 views
2

제품에 범주를 추가 할 수 있지만 제품이 포함 된 일부 범주가 있습니다. 이것은 다 대다 관계이며 제품은 카테고리와의 관계를 알지 못합니다 (범주 내에서만 저장되므로). 먼저 설정을 게시 한 다음 문제가되는 쿼리를 게시합니다. 일부 데이터를하기 위해

/** @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; 
} 

는,이처럼 만들 :

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 } 

지금 조회 할 :

$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를 들여다 보면, 지금 다음과 같은 데이터가 이 데이터 : 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' 
,210

하지만 라운드 다른 방법으로 데이터를 조회 할 경우 : 범주를 얻기 모든 제품을 받고, 카테고리는 있습니다

$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 

어떤 제품이 표시되지 않고 나는 치명적인 오류 얻을 :

을 나는 MongoDB를 로그에 보면
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 

쿼리는 다음과 같다 :

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 태어나 셨를 ds 배열이지만 JSON 배열은 없습니다. 하지만 어떻게 수리해야할지 모르겠다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 이 특별한 문제에 답할 수 없다면 MongoDB에 Doctrine을 사용하는 예제를 제공해 주실 수 있습니까? 여기서 이와 같이 많은 관계가 있고 많은 양의 데이터를 쿼리 할 수 ​​있습니까?

업데이트 : 나는 아마도 doctrine의 어떤 버전을 사용했는지 언급 했어야합니다. 나는이 설정을 사용 :

{ 
    "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 .... 잘 작동합니다. 그러나 이것에 대한 어떤 설명도 여전히 환영받습니다. 여기서 무슨 일이 일어 났는지 알고 싶습니다. 고마워.

+0

음, DBREF를 피해야합니다 (http://www.transmachina.com/en/knowledge-resources/mongo-tip-avoid-dbref-all-costs). ,'구조 잘.제품 컬렉션에는 카테고리 ref가 있어야하며 '그 반대도 아닙니다'. 그리고 나는 DBREF를 사용하지 못했습니다. 어쨌든 [How to DBREF] (http://stackoverflow.com/questions/6195286/how-to-query-mongodb-with-dbref) 및/또는 [Another Help] (http://stackoverflow.com)를보십시오./questions/8713304/mongodb-dbref) – Ravi

+0

의견을 보내 주셔서 감사합니다. 이것이 이제는 나를 위해 충분하기 때문에 이제는 단순한 ObjectId를 사용합니다. 하지만 내 문제 설명에서 언급 한 것과 같은 오류가 여전히 나타납니다. 그러나 당신은 재미있는 한가지를 말했습니다 : '그 반대도 아닙니다.' 그것에 대해 논증이 있습니까? 나는 너를 따라갈 수 없다. 왜 그 반대가 아닌가? – tester

+0

'반대의 경우도 마찬가지입니다. : 귀하의 경우 제품을 쿼리해야하는 경우 제품 ID 필드가있는 것처럼 '제품 및 범주'데이터를 가져 오기 위해 범주 컬렉션에 쿼리를 적용해야합니다. – Ravi

답변

2

발생한 버그는 PR #743으로 수정되었으며 1.0.0-BETA10에 포함되었습니다. MongoDB 2.6 (issue #741 참조)과의 호환성을 위해 필요한 몇 가지 수정 사항 중 하나였습니다. 서버가 쿼리 조건의 유효성 검사에 대해 더욱 엄격 해짐에 따라.

2.4 이전의 서버 버전은 $in의 개체를 허용하고 단순히 키를 무시했습니다. BSON specification을 살펴보면, 배열과 객체가 타입 코드와 매우 유사한 구조를 가지고 있음을 알 수 있습니다. 각각은 일련의 키/값 쌍이며 배열 페이로드는 순차적 숫자 문자열을 키로 가지는 객체와 매우 유사하게 보입니다. 그래서 이전 버전의 서버가 두 가지 유형 중 하나를 받아들이는 것이 왜 쉬운지를 설명해야합니다.