Querying an array of objects with the PHP driver

17 views
Skip to first unread message

Mike Dransfield

unread,
Nov 22, 2011, 8:49:31 PM11/22/11
to mongodb-user
I have a collection of products with attribute names and values.

Some example data would be like this

> db.product.save({name:'product1', attrs:[{name:'attr1', value:'a'}, {name:'attr2', value:'b'}]})
> db.product.save({name:'product2', attrs:[{name:'attr1', value:'a'}, {name:'attr2', value:'c'}]})
> db.product.save({name:'product1', attrs:[{name:'attr1', value:'d'}, {name:'attr2', value:'b'}]})

> db.product.find()
{ "_id" : ObjectId("4ecc4c0523548e768a4e5694"), "name" : "product1", "attrs" : [        {       "name" : "attr1",       "value" : "a" },        {       "name" : "attr2",    "value" : "b" } ] }
{ "_id" : ObjectId("4ecc4c0a23548e768a4e5695"), "name" : "product2", "attrs" : [        {       "name" : "attr1",       "value" : "a" },        {       "name" : "attr2",    "value" : "c" } ] }
{ "_id" : ObjectId("4ecc4e4f23548e768a4e5696"), "name" : "product1", "attrs" : [        {       "name" : "attr1",       "value" : "d" },        {       "name" : "attr2",    "value" : "b" } ] }

I want to be able to query all products which have attr1=a AND attr2=b (ie only product1 in this example)

From the shell I can query like this

> db.product.find({attrs:[{name:'attr1', value:'a'}, {name:'attr2', value:'b'}]});
{ "_id" : ObjectId("4ecc4c0523548e768a4e5694"), "name" : "product1", "attrs" : [        {       "name" : "attr1",       "value" : "a" },        {       "name" : "attr2",    "value" : "b" } ] }


From PHP this translates to

$m = new \Mongo();
$db = $m->test;
$c = $db->product;
$query = array(
      'attrs'=>array(array('name'=>'attr2', 'value'=>'b'), array('name'=>'attr1', 'value'=>'a'))
);
print_r($query);
$cursor = $c->find($query);
echo $cursor->count();
 foreach ($cursor as $row) {
    print_r($row);
}

This outputs "0" but it should be "1"

Is this a bug/limitation in the driver or am I doing something wrong?

If I change $query to this

$query = array('attrs'=>array('name'=>'attr2', 'value'=>'b'));

Then it returns 2 rows, but this is not what I want

I also tried this as the query

Array
(
    [attrs] => Array
        (
            [0] => stdClass Object
                (
                    [name] => attr2
                    [value] => b
                )
            [1] => stdClass Object
                (
                    [name] => attr1
                    [value] => a
                )
        )
)

Fanzhou

unread,
Nov 23, 2011, 1:52:57 AM11/23/11
to mongodb-user
The order of attrs items is wrong. It should be as followed.
$query = array('attrs'=>array(array('name'=>'attr1',
'value'=>'a'),array('name'=>'attr2', 'value'=>'b'))
Reply all
Reply to author
Forward
0 new messages