在$ unwind和$ lookup之后回滚两个嵌套数组字段的数据,并在$ project中反映日期范围上的$ filter

时间:2017-07-11 11:33:27

标签: mongodb aggregation-framework

{
    "_id" : ObjectId("590b12b6330e1567acd29e69"),
    "name": "Foo",
    "sales_history" : [ 
        {
            "_id" : ObjectId("593ce8e4cfaa652df543d9e3"),
            "sold_at" : ISODate("2017-06-11T06:53:24.881Z"),
            "sold_to" : ObjectId("593509e938792e046ba14a02"),
            "sold_products" : [ 
                {
                    "product_dp" : 100,
                    "quantity" : 1,
                    "product_id" : ObjectId("591068be1f4c6c79a442a788"),
                    "_id" : ObjectId("593ce8e4cfaa652df543d9e5")
                }, 
                {
                    "product_dp" : 100,
                    "quantity" : 1,
                    "product_id" : ObjectId("593a33dccfaa652df543d924"),
                    "_id" : ObjectId("593ce8e4cfaa652df543d9e4")
                }
            ]
        }, 
        {
            "_id" : ObjectId("5944cb7142a04740357020b9"),
            "sold_at" : ISODate("2017-06-17T06:25:53.332Z"),
            "sold_to" : ObjectId("5927d4a59e58ba0c61066f3b"),
            "sold_products" : [ 
                {
                    "product_dp" : 500,
                    "quantity" : 1,
                    "price" : 5650,
                    "product_id" : ObjectId("593191ed53a2741dd9bffeb5"),
                    "_id" : ObjectId("5944cb7142a04740357020ba")
                }
            ]
        }
     ]
}

我有这样的用户架构。我想要product_id参考的详细信息,并在sold_at日期字段中使用日期范围搜索条件。

当我在sold_at搜索时,我的预期数据如下:2017-06-11

{
     "_id" : ObjectId("590b12b6330e1567acd29e69"),
     "name": "Foo",
     "sales_history" : [ 
         {
             "_id" : ObjectId("593ce8e4cfaa652df543d9e3"),
             "sold_at" : ISODate("2017-06-11T06:53:24.881Z"),
             "sold_to" : ObjectId("593509e938792e046ba14a02"),
             "sold_products" : [ 
                 {
                     "product_dp" : 100,
                     "quantity" : 1,
                     "product_id": {
                         _id:ObjectId("hsfgg123412yh3gy1u2g3"), 
                         name: "Product1", 
                         code: "FG0154"
                      },
                 }
             ] 
          }
        ]
       }

需要在product_id中填充产品详细信息,sales_history数组需要在日期范围内进行过滤。

1 个答案:

答案 0 :(得分:2)

您可以尝试以下聚合查询。

日期范围内的

$filter sales history后跟$unwind sales history& sold_products

$lookup sold_products获取产品详情。

$group返回sold_products& sales history

db.collection.aggregate([
  {
    "$project": {
      "name": 1,
      "sales_history": {
        "$filter": {
          "input": "$sales_history",
          "as": "history",
          "cond": {
            "$and": [
              {
                "$gte": [
                  "$$history.sold_at",
                  ISODate("2017-06-11T00:00:00.000Z")
                ]
              },
              {
                "$lt": [
                  "$$history.sold_at",
                  ISODate("2017-06-12T00:00:00.000Z")
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    "$unwind": "$sales_history"
  },
  {
    "$unwind": "$sales_history.sold_products"
  },
  {
    "$lookup": {
      "from": lookupcollection,
      "localField": "sales_history.sold_products.product_id",
      "foreignField": "_id",
      "as": "sales_history.sold_products.product_id"
    }
  },
  {
    "$group": {
      "_id": {
        "_id": "$_id",
        "sales_history_id": "$sales_history._id"
      },
      "name": {
        "$first": "$name"
      },
      "sold_at": {
        "$first": "$sales_history.sold_at"
      },
      "sold_to": {
        "$first": "$sales_history.sold_to"
      },
      "sold_products": {
        "$push": "$sales_history.sold_products"
      }
    }
  },
  {
    "$group": {
      "_id": "$_id._id",
      "name": {
        "$first": "$name"
      },
      "sales_history": {
        "$push": {
          "_id": "$_id.sales_history_id",
          "sold_at": "$sold_at",
          "sold_to": "$sold_to",
          "sold_products": "$sold_products"
        }
      }
    }
  }
]);