遍历mongo文档数组并获取嵌套数组属性的计数?

时间:2018-12-12 14:19:48

标签: mongodb mongodb-query aggregation-framework

我有一系列形状像这样的酒店:

[
  {
      "_id" : ObjectId("..."),
      "Reviews" : [ 
          {
              "Ratings" : {
                  "Service" : 4.0,
                  "Cleanliness" : "4",
                  "Overall" : 4.0,
                  "Value" : 4.0,
                  "Sleep Quality" : "4",
                  "Rooms" : "4",
                  "Location" : "5"
              },
              "AuthorLocation" : "...",
              "Title" : "...",
              "Author" : "...",
              "ReviewID" : "...",
              "Content" : "...",
              "Date" : ISODate("...")
          }, 
          {
              "Ratings" : {
                  "Cleanliness" : "5",
                  "Overall" : 5.0,
                  "Value" : 4.0,
                  "Service" : 5.0,
                  "Rooms" : "5"
              },
              "AuthorLocation" : "...",
              "Title" : "...",
              "Author" : "...",
              "ReviewID" : "...",
              "Content" : "...",
              "Date" : ISODate("...")
          }
      ],
      "HotelInfo" : {
          "Name" : "Hilton Garden Inn Baltimore White Marsh",
          "HotelURL" : "...",
          "Price" : "...",
          "Address" : "...",
          "HotelID" : "...",
          "ImgURL" : "..."
      }
  },
  ... // More hotel entries
]

我基本上想做的是遍历数组中的每个酒店文档,并获取带有酒店名称及其具有多少五星级"Overall"评级的对象的列表。

所需的输出:

{ _id: "Hiltop Inn", numberOfFiveStarReviews: 3 },
{ _id: "Hot Hotel", numberOfFiveStarReviews: 2 },
{ _id: "Cool Hotel", numberOfFiveStarReviews: 6 }

我已经坚持了一段时间,并尝试使用filter或其他聚合工具进行各种操作,但是我无法使其正常工作。

这是我到目前为止所拥有的:

db.reviews.aggregate([
  { $unwind: "$Reviews" },
  { $unwind: "$Reviews.Ratings" },
  { 
      $group : { 
          _id: "$HotelInfo.Name", 
          countOfFiveStarRatings: {  
              // NOT SURE WHAT TO DO HERE
          } 
      } 
  }
])

不确定是否有更好的方法可以解决此问题,但这是我一段时间以来一直在使用的方法。我对MongoDB有点陌生,所以任何帮助都将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

了解到我可以继续做project并使用过去的结果直到我得到想要的结果之后,我才能够解决这个问题。

解决方案:

db.reviews.aggregate([
    { $unwind: "$Reviews" },
    { $unwind: "$Reviews.Ratings" },
    {
        $group : {
            _id: "$HotelInfo.Name",
            reviews: {
                $push: "$Reviews.Ratings.Overall"
            }
        }
    },
    {
        $project: {
            _id: 1,
            fiveStarReviews: {
                $filter: {
                    input: "$reviews",
                    as: "rev",
                    cond: {
                        $eq: ["$$rev", 5]
                    }
                }
            }
        }
    },
    {
        $project: {
            _id: 0,
            name: "$_id",
            countOfFiveStarReviews: {
                $size: "$fiveStarReviews"
            }
        }
    }
])