如何在Moongoose

时间:2018-01-09 16:29:56

标签: mongodb aggregation-framework

我在收集酒店有复杂的文件,我想只投影酒店名称,_id,城市和特定酒店的标准间,豪华套房和套房,我该怎么做。

这是我的文件

{
"_id" : ObjectId("59f9b27970bc1d12048e323f"),
"type" : "variable",
"country" : "Uae",
"city" : "Dubai",
"rating" : "3 star",
"name" : "taj",
"rooms" : [ 
    {
        "roomNo" : "12",
        "type" : "Standard",
        "maxOccupancy" : "3",
        "reserved" : [ 
            {
                "from" : "2017-12-06",
                "to" : "2017-12-08"
            }
        ],
        "mealPlan" : [ 
            {
                "type" : "AP",
                "perDblRoom" : "10,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "17,355",
                "season" : "high"
            }, 
            {
                "type" : "AP",
                "perDblRoom" : "9,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "6,355",
                "season" : "low"
            }, 
            {
                "type" : "CAP",
                "perDblRoom" : "10,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "17,355",
                "season" : "high"
            }, 
            {
                "type" : "CAP",
                "perDblRoom" : "9,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "6,355",
                "season" : "low"
            }
        ]
    }, 
    {
        "roomNo" : "10",
        "type" : "Deluxe",
        "maxOccupancy" : "6",
        "reserved" : [ 
            {
                "from" : "2017-12-09",
                "to" : "2017-12-12"
            }, 
            {
                "from" : "2017-12-13",
                "to" : "2017-12-16"
            }, 
            {
                "from" : "2017-12-18",
                "to" : "2017-12-20"
            }
        ],
        "mealPlan" : [ 
            {
                "type" : "AP",
                "perDblRoom" : "10,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "17,355",
                "season" : "high"
            }, 
            {
                "type" : "AP",
                "perDblRoom" : "9,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "6,355",
                "season" : "low"
            }, 
            {
                "type" : "CAP",
                "perDblRoom" : "10,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "17,355",
                "season" : "high"
            }, 
            {
                "type" : "CAP",
                "perDblRoom" : "9,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "6,355",
                "season" : "low"
            }
        ]
    }, 
    {
        "roomNo" : "8",
        "type" : "Suite",
        "maxOccupancy" : "6",
        "reserved" : [ 
            {
                "from" : "2017-12-09",
                "to" : "2017-12-12"
            }, 
            {
                "from" : "2017-12-13",
                "to" : "2017-12-14"
            }, 
            {
                "from" : "2017-12-18",
                "to" : "2017-12-20"
            }
        ],
        "mealPlan" : [ 
            {
                "type" : "AP",
                "perDblRoom" : "10,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "17,355",
                "season" : "high"
            }, 
            {
                "type" : "AP",
                "perDblRoom" : "9,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "6,355",
                "season" : "low"
            }, 
            {
                "type" : "CAP",
                "perDblRoom" : "10,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "17,355",
                "season" : "high"
            }, 
            {
                "type" : "CAP",
                "perDblRoom" : "9,334",
                "extraPaxWithBed" : "3,953",
                "extraPaxChildWithBed" : "3,953",
                "extraPaxChildNoBed" : "2,682",
                "perSglRoom" : "6,355",
                "season" : "low"
            }
        ]
    }
]
 }

我想要的输出应该是

{
 "_id" : ObjectId("59f9b27970bc1d12048e323f"),
  "name" : "taj",
  "rating" : "3 star",
  "city" : "Dubai",
  "standard" : 4, // count of standard rooms in the hotel
  "deluxe" : 4,
  "suite" : 4
},{
 "_id" : ObjectId("59f9b27970bc1d12048e3233"),
  "name" : "hyatt",
  "rating" : "3 star",
  "city" : "Dubai",
  "standard" : 4, // count of standard rooms in the hotel
  "deluxe" : 4,
  "suite" : 4
}

这是我需要从酒店集合中输出的输出,我在mongodb文档中阅读很多,并且遇到了像展开项目和组这样的方法,但无法找到输出的方法

查询:

Hotel.aggregate(
        [{
            "$project": {
              "top": {
                "_id": "$_id",
                "name": "$name",
                "rating": "$rating",
                "city": "$city"
              },
              "rooms": 1
            }
          },
          {
            "$unwind": "$rooms"
          },
          {
            "$group": {
              "_id": {
                "id": "$_id",
                "type": "$rooms.type"
              },
              "count": {
                "$sum": 1
              },
              "top": {
                "$first": "$top"
              }
            }
          },
          {
            "$sort": {
              "_id.type": 1
            }
          },
          {
            "$group": {
              "_id": "$_id.id",
              "top": {
                "$first": "$top"
              },
              "typeandcount": {
                "$push": {
                  "k": "$_id.type",
                  "v": "$count"
                }
              },
            }
          },
          {"$replaceRoot":{
            "newRoot":{
              "$arrayToObject":{
                "$concatArrays":[
                  {"$objectToArray":"$top"},
                  "$typeandcount"
                ]
              }
            }
          }}
        ]
      )

1 个答案:

答案 0 :(得分:0)

您可以在3.6版本中尝试以下聚合。

添加要保留在输出响应中的所有顶部字段。首先$group创建计数类型的酒店类型和第二组创建类型和计数值对的数组,然后$mergeObjects将顶部键值与$arrayToObject合并,生成类型键和计数值对,以生成预期的响应。

$replaceRoot将文档提升到最高级别。

db.colname.aggregate([
  {"$project":{
    "top":{"_id":"$_id","name":"$name","rating":"$rating","city":"$city"},
    "rooms":1
  }},
  {"$unwind":"$rooms"},
  {"$group":{
    "_id":{"id":"$_id","type":"$rooms.type"},
    "count":{"$sum":1},
    "top":{"$first":"$top"}
  }},
  {"$group":{
    "_id":"$_id.id",
    "top":{"$first":"$top"},
    "typeandcount":{"$push":{"k":"$_id.type","v":"$count"}}
  }},
  {"$replaceRoot":{
    "newRoot":{"$mergeObjects":["$top",{"$arrayToObject":"$typeandcount"}]}
  }}
])

3.4

替换最后阶段
{"$replaceRoot":{
  "newRoot":{
    "$arrayToObject":{
      "$concatArrays":[
        {"$objectToArray":"$top"},
        "$typeandcount"
      ]
    }
  }
}}