我有这种结构的MongoDB文档:
{
_id: 1
dates: [
ISODate ("2015-08-21T22: 00: 00Z")
ISODate ("2015-09-27T22: 00: 00Z")
],
...
}
在我的示例中,我们看到文档1已被访问:
在我的申请中,我可以按时间段(开始日期,结束日期)进行过滤。
如果在我的申请中我过滤了期间" 2015-09-01 - 2015-09-01":
逻辑上不应该找到文件1,因为在此期间没有查阅过。但是通过我的测试,找到了文档1.
我必须使用什么条件来正确过滤数据?
我试过了,但这是错误的:
<?php
$begin = new \DateTime('2015-09-01');
$end = new \DateTime('2015-09-01');
$expr1 = $qb->expr()->field('dates')->gte($begin);
$expr2 = $qb->expr()->field('dates')->lte($end);
$qb
->addAnd($expr1)
->addAnd($expr2)
;
感谢您的帮助, Yohann
答案 0 :(得分:0)
汇总
这是你可以尝试的mongoshell的代码片段
> db.collection.aggregate([{$unwind:"$dates"},{$match:{"dates":{$gt:new ISODate("2015-01-01"),$lt:new ISOD
ate("2015-09-01")}}}])
使用查询查询
db.collection.find({dates:{$elemMatch:{$gt:new ISODate("2015-01-10"),$lt:new ISODate("2015-09-01")}}},{"dates.$":1})
答案 1 :(得分:0)
谢谢大家,我用你的答案解决了问题,经过全面测试。
使用教义odm做到这一点很难,这是解决方案:
<?php
$begin = new \DateTime($options['begin']);
$end = new \DateTime($options['end']);
$expr = $qb->expr()
->gte($begin)
->lte($end)
;
$exprElementMatch = $qb->expr()->field('dates')->elemMatch($expr);
$qb->addAnd($exprElementMatch);
答案 2 :(得分:0)
目前标记为已解决的答案实际上并不适用于我。
鉴于以下数据:
{
_id: 1
dates: [
ISODate("2015-08-21T22:01:12Z")
ISODate("2015-08-22T00:06:45Z")
],
...
}
以下查询与上述文档匹配:
db.collection.find({dates:{$elemMatch:{$gt:new ISODate("2017-08-21"),$lt:new ISODate("2017-08-22")}}}
我很困惑并阅读了$elemMatch documentation并说明了:
$ elemMatch运算符将查询结果中字段的内容限制为仅包含与$ elemMatch条件匹配的第一个元素。
因此,根据这个已解决的问题,这根本无法正常工作。对于我的用例,我能够仅使用以下查询来评估dates
数组中的第一个元素来过滤我的文档。
db.collection.find({"dates.0":{$gte:new ISODate("2017-07-02"),$lt:new ISODate("2017-07-03")})
This answer详细介绍了如何实际查询dates
数组。