1

I want to execute Document Nested in an Array queries with the Doctrine mongodb odm query builder

I have basically a structure similar to :

db.inventory.insertMany( [

{ item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },

{ item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },

{ item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }

]);

I want to execute this shell query within the query builder

db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )

I have tried this, but this won't work as it ignores the field 'instock'.

$qb->field('instock')->field('warehouse')->equals('A')->field('qty')->equals(5)

Keep in mind that doing the following

$qb->field('instock.warehouse')->equals('A')->field('instock.qty')->equals(5)

is a different logic (check second example), because it matches not necessarily the same embedded document.

I can implement it using $where and a loop, but it is ugly and slow. any better ideas ?

2 Answers 2

3

using $elemMatch, this is the way to solve this issue :

$qb->expr()->field('instock')->elemMatch(
        $qb->expr()
            ->field('warehouse')->equals('A')
            ->field('qty')->equals(5)
);
Sign up to request clarification or add additional context in comments.

Comments

1

ODM supports embedded documents via query builder so you can do the following:

$qb->field('instock')->equals(new InStock('A', 5));

If using objects is not what you want I think you can do away with associative array instead of new InStock().

4 Comments

that way i would need the whole object data, i can't look for a specific field :(
@volkovmqx sorry then, was mislead by query using all fields that were in the data. Have you tried something like $qb->field('instock')->equals(['warehouse' => 'A', 'qty' => 5]);?
yes, it will match if a whole ['warehouse' => 'A', 'qty' => 5] exists, and in the same order, so ['warehouse' => 'A'] won't work
yes, that's how i solved this issue. i will share the answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.