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

Doctrine Mongodb ODM Add Dynamic Dates in Aggregation

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

我的架构如下:


    {
        "_id" : ObjectId("575b7c0b0419c906e262d54b"),
        "customer" : {
            "id" : ObjectId("575b7c0b0419c906e262d54b")
        },
        "name" : "Harley Store",
        "description" : "Harley Store",
        "contracts" : [
            {
                "_id" : ObjectId("575b7c0b0419c906e262d54b"),
                "bike" : {
                    "id" : ObjectId("575b7c0b0419c906e262d54b")
                },
                "from" : ISODate("2050-01-01T00:00:00.000Z"),
                "till" : ISODate("2050-01-05T00:00:00.000Z"),
                "cost" : 10000,
                "lapse" : [
                    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"),
                "bike" : {
                    "id" : ObjectId("575b7c0b0419c906e262d54c")
                },
                "from" : ISODate("2050-01-01T00:00:00.000Z"),
                "till" : ISODate("2050-01-05T00:00:00.000Z"),
                "cost" : 10000,
                "lapse" : [
                    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:'$contracts'
        },
        {
            $project:{
                contract:'$contracts', 
                _id: 0
            }
        }, 
        {
            $match:{
                'contract.bike.id': ObjectId("575b7c0b0419c906e262d54b")
            }
        }, 
        {
            $match:{
                $or: [
                {'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 中的查询工作正常,但日期是动态生成的,我无法使用查询生成器找到完成此操作的方法。

我的查询生成器:


    public function hasContracts(string $bikeId, \DateTime $from, \DateTime $till): bool
    {
        $filterDate = \DateTimeImmutable::createFromMutable($from);
        $days = $from->diff($till)->days;
        $qb = $this->createAggregationBuilder();
        $qb->unwind('$contracts');
        $qb->project()
            ->field('contract')
            ->expression('$contracts')
            ->field('_id')
            ->expression(0);
        $qb->match()->field('contract.bike.id')->equals(new ObjectId($bikeId));

        for($i;$days){ //$i menor or equal $days
            $qb->match()->addOr(
                $qb->matchExpr()->field('contract.lapse')->equals(
                    new UTCDateTime(
                        $filterDate->add(
                            \DateInterval::createFromDateString(sprintf('%d day', $i)))
                        ->setTime(0, 0)->getTimestamp() * 1000
                    )
                )
            );
        }

        return 0 !== $qb->execute()->count();
    }

生成 odm 的查询如下:


    {
      "aggregate": true,
      "pipeline": [
        {
          "$unwind": "$contracts"
        },
        {
          "$project": {
            "contract": "$contracts",
            "_id": 0
          }
        },
        {
          "$match": {
            "contract.bike.id": {
              "$oid": "575b7c0b0419c906e262d54b"
            }
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2524780800000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2524867200000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2524953600000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525040000000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525126400000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525212800000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525299200000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525385600000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525472000000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525558400000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525644800000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525731200000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525817600000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525904000000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2525990400000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526076800000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526163200000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526249600000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526336000000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526422400000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526508800000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526595200000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526681600000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526768000000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526854400000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2526940800000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2527027200000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2527113600000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2527200000000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2527286400000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2527372800000"
                  }
                }
              }
            ]
          }
        },
        {
          "$match": {
            "$or": [
              {
                "contract.lapse": {
                  "$date": {
                    "$numberLong": "2527459200000"
                  }
                }
              }
            ]
          }
        }
      ],
      "options": {
        "cursor": true
      },
      "db": "store",
      "collection": "BikeStore"
    }

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

谢谢你的帮助!!!

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

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