MongoDb 创建聚合 创建查询

Posted

技术标签:

【中文标题】MongoDb 创建聚合 创建查询【英文标题】:MongoDb Create Aggregate Create query 【发布时间】:2021-09-14 23:30:45 【问题描述】:

我有 3 个表用户,班次,临时班次,

shifts:[_id:ObjectId(2222),name:"Morning",_id:ObjectId(454),name:"Night"]
users:[_id:ObjectId(123),name:"Albert",shift_id:ObjectId(2222)]

temporaryShifts:[
_id:2,userId:ObjectId(123),shiftId:ObjectId(454),type:"temporary",date:"2020-02-01",
_id:987,userId:ObjectId(123),shiftId:ObjectId(454),type:"temporary",date:"2020-02-03",
_id:945,userId:ObjectId(123),shiftId:ObjectId(454),type:"temporary",date:"2020-02-08",
_id:23,userId:ObjectId(123),shiftId:ObjectId(454),date:"2020-02-09"]

我想做一个猫鼬聚合查询然后给我结果: 在两个日期之间获取结果,例如:2020-02-01 2020-02-05, 结果是:

[
_id:ObjectId(123),name:"Albert",shift:[
_id:2,shiftId:ObjectId(454),type:"temporary",date:"2020-02-01",
_id:2,shiftId:ObjectId(2222),type:"permanent",date:"2020-02-02",
_id:2,shiftId:ObjectId(454),type:"temporary",date:"2020-02-03",
_id:2,shiftId:ObjectId(2222),type:"permanent",date:"2020-02-04",
_id:2,shiftId:ObjectId(2222),type:"permanent",date:"2020-02-05",
]
]

在结果类型中临时表示在表中选择的日期temporaryShift文档可用,否则类型为永久

MongoPlayGround You Can edit

【问题讨论】:

【参考方案1】:

您可以首先使用$range 投影日期范围数组,在您的示例中,它将类似于 [2020-02-01, 2020-02-02, 2020-02-03, 2020-02-04, 2020- 02-05],那么就可以使用数组来执行$lookup

db.users.aggregate([
  
    $limit: 1
  ,
  
    "$addFields": 
      "startDate": ISODate("2020-02-01"),
      "endDate": ISODate("2020-02-05")
    
  ,
  
    "$addFields": 
      "dateRange": 
        "$range": [
          0,
          
            $add: [
              
                $divide: [
                  
                    $subtract: [
                      "$endDate",
                      "$startDate"
                    ]
                  ,
                  86400000
                ]
              ,
              1
            ]
          
        ]
      
    
  ,
  
    "$addFields": 
      "dateRange": 
        $map: 
          input: "$dateRange",
          as: "increment",
          in: 
            "$add": [
              "$startDate",
              
                "$multiply": [
                  "$$increment",
                  86400000
                ]
              
            ]
          
        
      
    
  ,
  
    "$unwind": "$dateRange"
  ,
  
    "$project": 
      "name": 1,
      "shiftId": 1,
      "dateCursor": "$dateRange"
    
  ,
  
    "$lookup": 
      "from": "temporaryShifts",
      "let": 
        dateCursor: "$dateCursor",
        shiftId: "$shiftId"
      ,
      "pipeline": [
        
          "$addFields": 
            "parsedDate": 
              "$dateFromString": 
                "dateString": "$date",
                "format": "%Y-%m-%d"
              
            
          
        ,
        
          $match: 
            $expr: 
              $and: [
                
                  $eq: [
                    "$$dateCursor",
                    "$parsedDate"
                  ]
                
              ]
            
          
        
      ],
      "as": "temporaryShiftsLookup"
    
  ,
  
    "$unwind": 
      path: "$temporaryShiftsLookup",
      preserveNullAndEmptyArrays: true
    
  ,
  
    $project: 
      shiftId: 1,
      type: 
        "$ifNull": [
          "$temporaryShiftsLookup.type",
          "permanent"
        ]
      ,
      date: "$dateCursor"
    
  
])

这里是Mongo Playground 供您参考。

【讨论】:

以上是关于MongoDb 创建聚合 创建查询的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB按聚合查询分组

MongoDB 聚合 $group 阶段已从外部创建的值/变量

在 mongodb 聚合框架中展开字典值

Mongodb使用输入数组聚合

MongoDB 聚合与 Mongoose 虚拟

使用 ProjectionDefinition 和 c# 驱动程序的 Mongodb 组聚合