【问题标题】:$out ,$projection in mongodb$out ,$projection 在 mongodb
【发布时间】:2020-02-20 18:08:20
【问题描述】:

我想使用 $out 或 $merge 将记录保存在新集合中。

     **/////collection 2- reservationdeatils////**
         "_id":ObjectId("5e4a898947363e964a886420"),
         "phoneNo" : 98765#####,
         "name" : "name1",
         "userId":ObjectId("5e1efac668c3c811c83263cc"),
         "approversId":ObjectId("5e1efad268c3c811c83263cd")
         "bookedForDate":ISODate("2020-02-20T07:23:36.130Z"),
         "bookingDetails" : [
                    {    "_id" : ObjectId("5e44f471d1868d2a54aac12d"),
                         "seatsBooked" : 15,
                         "floorId" : "#IKE01",
                      },
                    {   "_id" : ObjectId("5e44f471d1868d2a54aac12c"),
                        "seatsBooked" : 35,
                        "floorId" : "#HKE04",
                    }
                 ],
     **/////collection 2-priceDetails////**
          {
           "_id" : ObjectId("5e1efb0168c3c811c83263ce"),
           "floorId" : "#IKE01",
           "weekday" : "monday",
            "pricePoint" : 589,
         }
         {
           "_id" : ObjectId("5e2694db54e532a4eb92b477"),
           "floorId" : "#IKE02",
           "weekday" : "thursday",
          "pricePoint" : 699
         }
        {
         "_id" : ObjectId("5e2694f954e532a4eb92b478"),
         "floorId" : "#HKE04",
         "weekday" : "monday",
         "pricePoint" : 579
        }
      **/////collection 3- discount////**
        {
        "_id" :  ObjectId("5e427de64617181a4ce38893"),
        "userId" : ObjectId("5e3d05ba964d0e06c4bb0f07"), 
        "approversId" : ObjectId("5e1d82156a67173cb877f67d"),
        "floorId" : "#IKE01",
        "weekday" : "monday",
        "discount" : 20%,
       },
       {
        "_id" :  ObjectId("5e4281e7fec2e01a4c60b406"),
        "userId" : ObjectId("5e1efac668c3c811c83263cc"), 
        "approversId" : ObjectId("5e1efad268c3c811c83263cd"),
        "floorId" : "#IKE01",
        "weekday" : "monday",
        "discount" : 24%,
     }

下面是我尝试过的查询:

     db.reservationdeatils.aggregate([
    {
       '$match': {
          'approverId': ObjectId('5e1efad268c3c811c83263cd'),
          'userId': ObjectId('5e1efac668c3c811c83263cc'),
          'bookedForDate': ISODate("2020-02-11T18:30:00Z"),
        }
     },
     {
      '$unwind': {
          'path': '$bookingDetails',
       },
     }, 
       {
        $lookup:
         {
          from: 'priceDetails',
          let: { floorId: '$bookingDetails.floorId' },
          pipeline: [
              {
                  $match: {
                      weekday: 'monday',
                      $expr: {
                          $eq: ["$floorId", "$$floorId"]
                      }
                  }
              }
          ], as: 'priceDetails'
      }
  },
  { '$unwind': '$priceDetails' },
    {
      $lookup:
      {
          from: 'discount',
          let: { floorId: '$bookingDetails.floorId' },
          pipeline: [
              {
                  $match: {
                      weekday: 'monday',
                      $expr: {
                          $eq: ["$floorId", "$$floorId"]
                      }
                  }
              }
          ], as: 'discounts'
      }
  },
  { '$unwind': '$discounts' },

  {
      '$group': {
          '_id': {
              'floorId': '$bookingDetails.floorId',
              'date': '$bookedForDate',
              'price': '$priceDetails.pricePoint',
              'discount': '$discounts.discount'
          },
          'seatsBooked': {
              '$sum': '$bookingDetails.seatsBooked'
          },
       }
   },
     {
      '$project': {
            'amount': {
              '$multiply':
                   [ 
                     '$seatsBooked',
                        {'$subtract': 
                              ['$_id.pricePoint',
                                 { '$multiply': 
                                   ['$_id.pricePoint', 
                                      { '$divide': 
                                        ['$_id.discount', 100] 
                                   }] 
                               }]
                            }]
                         },
                     },
                   },
      {
          $group: {
           _id: null,
            totalAmount: {
            $sum: "$amount"
          }
      }
  },
    {
      '$project': {
          _id:0,
          totalAmount:1,
          bookedForDate:1,
          'floorId':'$priceDetails.floorId'
       }  
     },{'$merge':'invoice'}
  ]).pretty()

我已经能够实现totalAmount,但我想要实现的是我想将这些字段保存到“发票”集合“userId”、“approversId”、“floorId”、“sum”、 totalSum","bookedForDate","name" 但是 1:每当我使用 $out 而不是 $merge 时,以前的文档都会得到我不想要的替换,2:如果我每次运行查询时都使用 $merge 一个新的文档已创建,并且也只有 _id:ObjectId(5e4a899c47363e964a88642f),totalBill:#### 这些字段,任何建议我该如何实现这一点

【问题讨论】:

  • 如果您使用的是 MongoDB v4.2,您可以使用 $set 在 MongoDB 中进行更新。
  • @– vikscool 是的,它的 v4.2 但是 $set ,它会创建一个新集合吗?我应该在查询的哪个位置使用它,或者你的意思是我应该构建另一个查询来更新它
  • 当您使用舞台$replaceRoot: { newRoot: "$bookingDetails" } 时,您清除了除seatsBooked 和 floorId 之外的所有其他数据。您将需要重新设计管道以保留数据,以便将其包含在最终文档中。
  • @joe 是的,你是对的,但如果我不使用这个阶段`$replaceRoot: { newRoot:"$bookingDetails"}`,那么我无法从 bookingDetails 数组对象中获取 floorId,如果你能建议的话我可以在查询中更改什么,我认为它会解决我的问题
  • @joe 我刚刚在我的问题中编辑了我的查询,请看一下,但投影仍然不起作用,只有 totalAmount 正在投影

标签: node.js mongodb aggregation-framework


【解决方案1】:

您正朝着一个好的方向前进,您只需要查看$group 聚合。

还有一件事我将折扣用作int 值,而不是百分比。

"discount" : 24

我已更新查询:

db.reservationdeatils.aggregate([
{
  $match: {
    "userId" : ObjectId("5e1efac668c3c811c83263cc"),
    "approversId" : ObjectId("5e1efad268c3c811c83263cd"),
    "bookedForDate" : ISODate("2020-02-20T07:23:36.130Z")
   }
},
{
 $unwind: {
     path: "$bookingDetails",
  },
}, 
{
 $lookup:
  {
   from: "priceDetails",
   let: { floorId: "$bookingDetails.floorId" },
   pipeline: [
       {
           $match: {
               weekday: "monday",
               $expr: {
                   $eq: ["$floorId", "$$floorId"]
               }
           }
       }
   ], 
   as: "priceDetails"
  }
},
{
  $unwind: "$priceDetails" 
},
{
 $lookup:
 {
     from: "discount",
     let: { floorId: "$bookingDetails.floorId" },
     pipeline: [
         {
             $match: {
                 weekday: "monday",
                 $expr: {
                     $eq: ["$floorId", "$$floorId"]
                 }
             }
         }
     ], 
     as: "discounts"
 }
}
,
{ 
  $unwind: "$discounts" 
}
,
{
 $group: {
     "_id": {
         "floorId": "$bookingDetails.floorId",
         "date": "$bookedForDate",
         "price": "$priceDetails.pricePoint",
         "discount": "$discounts.discount"
     },
     "price":{
      $first:"$priceDetails.pricePoint"
     },
     "discount":{
      $first:"$discounts.discount"
     },
     "seatsBooked": {
         $sum: "$bookingDetails.seatsBooked"
     },
  }
}
,
{
$project: {
  "amount": {
    $multiply:
      [
        "$seatsBooked",
        {
          $subtract:[
            "$price",
            {
              $multiply:[
                "$price",
                {
                  $divide:[
                    "$discount",
                    100
                  ]
                }
              ]
            }
          ]
        }
      ]
  },
},
}
,
{
 $group: {
  "_id": null,
   "totalAmount": {
   $sum: "$amount"
   }
  }
},
{
 $project: {
     "_id":0,
     "totalAmount":1,
     "bookedForDate":1,
     "floorId":"$priceDetails.floorId"
  }  
},
{
  $out:"invoice"
}
]).pretty()

这会对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多