【发布时间】:2019-04-15 08:50:05
【问题描述】:
我目前正在尝试转换此 JS 代码:
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 }
}
},
] }
}
}
] )
(根据官方文档:Use $all with $elemMatch
使用他们的聚合构建器进入 Doctrine ODM 代码:
$builder = $this->createAggregationBuilder();
$aggregation = $builder
->match()
->field('worklogs')
->all([
$builder->matchExpr()->elemMatch(
$builder->expr()->field('date')->lte($week->getEndDate())
)
])
;
但是,显然我无法正确匹配 $all - 这意味着我可以确保集合中的所有条目都满足 $elemMatch 检查的要求。
JS 中的原始 MongoDB 查询似乎可以解决问题,但我无法在 PHP 中接收相同的结果。到目前为止,我什至不确定 Doctrine 是否可以处理 $all 和 $elemMatch 的组合。
更新:
到目前为止,感谢大家的 cmets!然而,我仍在为$not / ->not() 运算符的当前查询语法(在 PHP 中!)苦苦挣扎。我已经在这里检查了文档:Doctrine ODM Docs,但找不到任何有用的东西。 (另请注意,我在这里使用的是 2.0 版)。
现在我的查询看起来像:
->match()
->field('worklogs')
->not([
$builder->matchExpr()->elemMatch(
$builder->matchExpr()->field('date')->gt($week->getEndDate())
)
])
但是会导致这个错误:
1) App\Tests\Repository\IssueRepositoryTest::testGetEstimationsPerWeek MongoDB\Driver\Exception\CommandException:$ 不需要正则表达式或文档 /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
【问题讨论】:
-
只是一个 PHP 翻译错误。这实际上是
->all([ [$builder->.... ] ]),注意额外的[]。只是 singular[](正如你所拥有的)在翻译中意味着{},所以你想要[ { ... } ],因此在老话中需要额外的[]或array()。 -
在这种特殊情况下,您既不需要 $all 也不需要 $elemMatch。
{$match: {"worklogs.date": {$lte: endDate}}}完全一样。 -
@AlexBlex 会不会也匹配集合中只有一个条目满足要求的结果?而我想要一个匹配所有元素的查询?
-
数组中只有 1 个 $elemMatch,所以它是 ALL 的 1 个元素。我认为您误解了 $all 的作用。如果您已经阅读了问题中发布的链接后面的页面,请滚动到顶部并重新阅读,注意每个单词。 mongodb 中的“集合”也用于指代文档集合 - 在您的情况下,“问题”是一个集合。 “工作日志”不是一个集合,而是一个文档、子文档或嵌入文档的数组。请遵守术语以避免混淆。
-
这两种形式实际上都不返回数组中的 ALL 元素 与条件匹配的位置。如果这就是您想要的,您实际上会将条件 反转 为
$gt并使用$not。即"worklogs": { "$not": { "$elemMatch": { "date": { "$gt": endDate } } } }。您在文档中指向的$all示例实际上适用于“多个条件”,而不是您假设的“所有数组元素”。
标签: php mongodb doctrine doctrine-odm