I am currently trying to convert this JS code:
db.Issue.aggregate( [
{ // Filter out issues that have been worked on after our given week = All worklogs muste have been before date
$match : {
worklogs: { $all: [
{
"$elemMatch" : {
date: { $lte: endDate }
}
},
] }
}
}
] )
(Based on official documentation: Use $all with $elemMatch
Into Doctrine ODM code using their aggregation builder:
$builder = $this->createAggregationBuilder();
$aggregation = $builder
->match()
->field('worklogs')
->all([
$builder->matchExpr()->elemMatch(
$builder->expr()->field('date')->lte($week->getEndDate())
)
])
;
However, apparently I am unable to match the $all
correctly - meaning in a way that allows me to ensure that all entries in a collection fulfilled the requirements checked by $elemMatch
.
The original MongoDB query in JS seems to do the trick, but I cannot manage to receive the same results in PHP. By now I am not even sure Doctrine can handle that combination of $all
and $elemMatch
.
UPDATE:
Thank you all for your comments so far! I am however still struggling with the current query syntax (in PHP!) for the $not
/ ->not()
operator. I have already checked the docs here: Doctrine ODM Docs but could not find anything useful. (Please also note, that I am using version 2.0 here).
Right now my query looks like:
->match()
->field('worklogs')
->not([
$builder->matchExpr()->elemMatch(
$builder->matchExpr()->field('date')->gt($week->getEndDate())
)
])
But leads to this error:
1) App\Tests\Repository\IssueRepositoryTest::testGetEstimationsPerWeek MongoDB\Driver\Exception\CommandException: $not needs a regex or a document /var/www/html/vendor/mongodb/mongodb/src/Operation/Aggregate.php:263 /var/www/html/vendor/mongodb/mongodb/src/Collection.php:223 /var/www/html/vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Aggregation/Builder.php:168 /var/www/html/vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Aggregation/Stage.php:35 /var/www/html/src/Repository/IssueRepository.php:85
->all([ [$builder->.... ] ])
, noting the additional[]
. Just the singular[]
( as you have ) means{}
in translation, So you want[ { ... } ]
and therefore the additional[]
orarray()
in older speak. – Neil Lunn{$match: {"worklogs.date": {$lte: endDate}}}
does exactly the same. – Alex Blex$gt
and use$not
. i.e"worklogs": { "$not": { "$elemMatch": { "date": { "$gt": endDate } } } }
. The$all
example you point to in the documentation actually applies as "multiple conditions", and not "ALL array elements" as you have presumed. – Neil Lunn