Mongo 使用日期时间戳的 $lookup 聚合

Mongo $lookup aggregation using date timestamps

我有两个 collections:汽车驾驶历史汽车地理位置。为了分析驾驶模式,我必须汇总驾驶历史并将它们 link 到汽车地理位置。

我使用 $match$project 聚合阶段来获取具有以下结构的驱动历史文档:

travelPurpose:<String>
carID:<ObjectId>
checkOutTime:<Date>
checkInTime:<Date>

下一步是使用$lookup阶段获取两个时间戳之间的汽车位置(checkOutTimecheckInTime) .每个汽车地理定位文档都有 carIDgeoLocationTimestamp 字段。如果我使用静态日期,例如:

{
  from: 'carGeoLocations',
  localField: 'carID',
  foreignField: 'carID',
  pipeline: [
    {$match: {
      geoLocationTimestamp: {
        $gte: ISODate('2022-01-01T00:00:00.000+0000'), 
        $lte: ISODate('2023-01-01T00:00:00.000+0000')
      }
    }}
  ],
  as: 'coordinates'
}

我确实得到了 1. 1. 2022 和 1. 1. 2023 之间的地理位置。Mongo 可以访问带有此行为示例的游乐场 here。 但是,如果我尝试使用基于 checkOutTimecheckInTime 值的动态日期,则不会检索到任何文档。 Mongo 带有此示例的游乐场可用 here。我尝试了以下方法:

{
 from: 'carGeoLocations',
 localField: 'carID',
 foreignField: 'carID',
 pipeline: [
   {$match: {
     geoLocationTimestamp: {
       $gte: "$checkOutTime", 
       $lte: "$checkInTime"
     }
   }}
 ],
 as: 'coordinates'
}

{
 from: 'carGeoLocations',
 localField: 'carID',
 foreignField: 'carID',
 let: {t1: '$checkOutTime', t2: '$checkInTime'}
 pipeline: [
   {$match: {
     geoLocationTimestamp: {
       $gte: '$$t1', 
       $lte: '$$t2'
     }
   }}
 ],
 as: 'coordinates'
}

结果相同。有人能发现我的方法有什么问题吗?

首先查找然后使用 geoLocationTimestamp 匹配
试试下面的代码

 {
        $lookup:{
         from: 'carGeoLocations',
         localField: 'carID',
         foreignField: 'carID',
         as: 'coordinates'
        }
        },
        {
        $match:{
           geoLocationTimestamp: {
             $gte:'$coordinates.checkOutTime',
             $lte:'$coordinates.checkInTime'
            }
          }
        }

更新

经过进一步的实验,当你想在 $lookup 聚合阶段使用用 let 声明的变量时,你需要使用 $expr

我的查找阶段现在看起来像这样:

{
    "$lookup": {
      "from": "carGeoLocations",
      "localField": "carID",
      "foreignField": "carID",
      "let": {
        t1: "$checkOutTime",
        t2: "$checkInTime"
      },
      "pipeline": [
        {
          $match: {
            $and: [
              {
                $expr: {
                  $gte: [
                    "$geoLocationTimestamp",
                    "$$t1"
                  ],
                }
              },
              {
                $expr: {
                  $lte: [
                    "$geoLocationTimestamp",
                    "$$t2"
                  ],
                }
              },
            ]
          }
        }
      ],
      "as": "coordinates"
    }
  }