Doctrine Mongodb ODM 在聚合中添加动态日期

Posted

技术标签:

【中文标题】Doctrine Mongodb ODM 在聚合中添加动态日期【英文标题】:Doctrine Mongodb ODM Add Dynamic Dates in Aggregation 【发布时间】:2019-04-16 13:16:20 【问题描述】:

我想知道日期范围内的特定摩托车是否有合同。

我的架构如下:

“_id”:ObjectId(“575b7c0b0419c906e262d54b”), “顾客” : “id”:ObjectId(“575b7c0b0419c906e262d54b”) , “名称”:“哈雷商店”, “描述”:“哈雷商店”, “合同”:[ “_id”:ObjectId(“575b7c0b0419c906e262d54b”), “自行车” : “id”:ObjectId(“575b7c0b0419c906e262d54b”) , “来自”:ISODate(“2050-01-01T00:00:00.000Z”), “直到”:ISODate(“2050-01-05T00:00:00.000Z”), “成本”:10000, “失误”:[ ISODate("2050-01-01T00:00:00.000Z"), ISODate("2050-01-02T00:00:00.000Z"), ISODate("2050-01-03T00:00:00.000Z"), ISODate("2050-01-04T00:00:00.000Z"), ISODate("2050-01-05T00:00:00.000Z") ] , "_id" : ObjectId("575b7c0b0419c906e262d54c"), “自行车” : “id”:ObjectId(“575b7c0b0419c906e262d54c”) , “来自”:ISODate(“2050-01-01T00:00:00.000Z”), “直到”:ISODate(“2050-01-05T00:00:00.000Z”), “成本”:10000, “失误”:[ ISODate("2050-01-06T00:00:00.000Z"), ISODate("2050-01-07T00:00:00.000Z"), ISODate("2050-01-08T00:00:00.000Z"), ISODate("2050-01-09T00:00:00.000Z") ] ]

我在 mongo shell 中有以下查询:

db.getCollection('BikeStore').aggregate([ $unwind:'$合约' , $项目: 合同:'$合同', _id: 0 , $匹配: 'contract.bike.id': ObjectId("575b7c0b0419c906e262d54b") , $匹配: $或:[ 'contract.lapse': $eq: ISODate("2049-01-31T00:00:00.000Z"), 'contract.lapse': $eq: ISODate("2050-02-01T00:00:00.000Z"), 'contract.lapse': $eq: ISODate("2050-02-02T00:00:00.000Z") ] ])

mongo shell 中的查询工作正常,但日期是动态生成的,我找不到使用查询生成器完成此操作的方法。

我的查询生成器:

公共函数 hasContracts(string $bikeId, \DateTime $from, \DateTime $till): bool $filterDate = \DateTimeImmutable::createFromMutable($from); $days = $from->diff($till)->days; $qb = $this->createAggregationBuilder(); $qb->unwind('$contracts'); $qb->项目() ->字段('合同') ->表达式('$contracts') ->字段('_id') ->表达式(0); $qb->match()->field('contract.bike.id')->equals(new ObjectId($bikeId)); for($i;$days) //$i 个月或等于 $days $qb->match()->addOr( $qb->matchExpr()->field('contract.lapse')->equals( 新的 UTCDateTime( $filterDate->添加( \DateInterval::createFromDateString(sprintf('%d day', $i))) ->setTime(0, 0)->getTimestamp() * 1000 ) ) ); 返回 0 !== $qb->execute()->count();

生成 odm 的查询如下:

“聚合”:是的, “管道”:[ "$unwind": "$contracts" , “$项目”: “合同”:“$合同”, “_id”:0 , “$匹配”: “合同.bike.id”: “$oid”:“575b7c0b0419c906e262d54b” , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2524780800000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2524867200000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2524953600000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525040000000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525126400000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525212800000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525299200000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525385600000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525472000000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525558400000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525644800000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525731200000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525817600000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525904000000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2525990400000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526076800000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526163200000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526249600000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526336000000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526422400000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526508800000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526595200000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526681600000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526768000000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526854400000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2526940800000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2527027200000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2527113600000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2527200000000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2527286400000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2527372800000" ] , “$匹配”: “$或”:[ “合同。失效”: “$日期”: "$numberLong": "2527459200000" ] ], “选项”: “光标”:真 , "db": "存储", “收藏”:“自行车商店”

如何将日期动态添加到匹配中而不重复匹配?

谢谢你的帮助!!!

【问题讨论】:

【参考方案1】:

每次调用$qb->match() 时,您都在创建一个新的$match 阶段。应该这样做:

$qb->match();
for($i;$days) //$i menor or equal $days
    $qb->addOr(/* ... */);

【讨论】:

以上是关于Doctrine Mongodb ODM 在聚合中添加动态日期的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine ODM:如何选择Mongodb数据库

Doctrine MongoDB 在没有 ODM 的情况下使用

Doctrine MongoDB 在没有 ODM 的情况下使用

Doctrine 2 ODM MongoDB 从内存中将图像存储在 GridFS 中

Doctrine ODM with MongoDB 需要两个参考映射集

Doctrine MongoDB ODM 在两个或多个字段中搜索