【问题标题】:Aggregate, Mongoose - ignores duplicated resultsAggregate, Mongoose - 忽略重复的结果
【发布时间】:2018-05-10 14:02:39
【问题描述】:

我有以下架构

var reviewSchema = new Schema({
    restaurantID: ObjectId,
    rating: {
     food: Number,
     service: Number,
     value: Number
    },
});

我想获得一系列平均食物、评级、服务评级,所以我这样做了

 Review.aggregate([
                    {
                        $match: {
                            restaurantID: mongoose.Types.ObjectId(reviewData.restaurantid)
                        }
                    },
                    {
                        $unwind: "$rating"
                    },
                    {
                        $group:{
                            _id: "$rating",
                            total_rating: { $avg: { $add: [ "$rating.food", "$rating.service", "$rating.value" ] } }
                        }
                    }
 ], function(review_error, reviews) {

但是,首先,它没有得到三个字段的平均值,它只得到字段的总和。没关系,我可以自己将其除以 3。最大的问题是它忽略了重复的结果。我尝试将结果打印出来:

 [ { _id: { food: 4, service: 5, value: 4 }, total_rating: 13 },
  { _id: { food: 5, service: 5, value: 5 }, total_rating: 15 } ]

我在集合中有 6 条 { _id: { food: 5, service: 5, value: 5 }, total_rating: 15 } 记录。我该如何解决这个问题?谢谢!

更新:示例

评论合集

{ 
    "_id" : ObjectId("5af3d804d0d09e18b098208f"), 
    "rating" : {
        "food" : NumberInt(5), 
        "service" : NumberInt(5), 
        "value" : NumberInt(5)
    }, 
    "restaurantID" : ObjectId("5ac962bd437c1e30e89406a8"), 
}
{ 
    "_id" : ObjectId("5af3d817d0d09e18b0982090"), 
    "rating" : {
        "food" : NumberInt(5), 
        "service" : NumberInt(5), 
        "value" : NumberInt(5)
    }, 
    "restaurantID" : ObjectId("5ac962bd437c1e30e89406a8"), 
}
{ 
    "_id" : ObjectId("5af3d89161cc0a0e60f0925d"), 
    "rating" : {
        "food" : NumberInt(4), 
        "service" : NumberInt(5), 
        "value" : NumberInt(4)
    }, 
    "restaurantID" : ObjectId("5ac962bd437c1e30e89406a8"), 
}

预期结果

[ { _id: { food: 5, service: 5, value: 5 }, total_rating: 15 },
  { _id: { food: 4, service: 5, value: 4 }, total_rating: 13 },
  { _id: { food: 5, service: 5, value: 5 }, total_rating: 15 } ]

实际结果

   [ { _id: { food: 4, service: 5, value: 4 }, total_rating: 13 },
     { _id: { food: 5, service: 5, value: 5 }, total_rating: 15 } ]

【问题讨论】:

  • 显示一小部分文档以及实际上可以“从该样本”获得的预期结果。这将使您更清楚地了解您实际需要实现的目标。
  • 我已经用一个小样本更新了帖子

标签: mongodb mongoose aggregation-framework


【解决方案1】:

不要$group。您只是试图“平均”文档中的值:

Review.aggregate([
  { "$addFields": {
     "average_rating": { "$avg": ["$rating.food", "$rating.service", "$rating.value" ]}
  }}
])

返回:

{
        "_id" : ObjectId("5af3d804d0d09e18b098208f"),
        "rating" : {
                "food" : 5,
                "service" : 5,
                "value" : 5
        },
        "restaurantID" : ObjectId("5ac962bd437c1e30e89406a8"),
        "average_rating" : 5
}
{
        "_id" : ObjectId("5af3d817d0d09e18b0982090"),
        "rating" : {
                "food" : 5,
                "service" : 5,
                "value" : 5
        },
        "restaurantID" : ObjectId("5ac962bd437c1e30e89406a8"),
        "average_rating" : 5
}
{
        "_id" : ObjectId("5af3d89161cc0a0e60f0925d"),
        "rating" : {
                "food" : 4,
                "service" : 5,
                "value" : 4
        },
        "restaurantID" : ObjectId("5ac962bd437c1e30e89406a8"),
        "average_rating" : 4.333333333333333
}

您真正想要的只是三个值的$avg 结果,您可以使用$addFields$project 简单地做到这一点。

$group 管道阶段用于“分组”,因此“相同值”被“分组”在一起。

此外,如果您真的想要“总计”,那么同样适用于 $sum

Review.aggregate([
  { "$addFields": {
     "average_rating": { "$avg": ["$rating.food", "$rating.service", "$rating.value" ]},
     "total_rating": { "$sum": ["$rating.food", "$rating.service", "$rating.value" ]}
  }}
])

“每个文档”的结果类似:

{
        "_id" : ObjectId("5af3d804d0d09e18b098208f"),
        "rating" : {
                "food" : 5,
                "service" : 5,
                "value" : 5
        },
        "restaurantID" : ObjectId("5ac962bd437c1e30e89406a8"),
        "average_rating" : 5,
        "total_rating" : 15
}
{
        "_id" : ObjectId("5af3d817d0d09e18b0982090"),
        "rating" : {
                "food" : 5,
                "service" : 5,
                "value" : 5
        },
        "restaurantID" : ObjectId("5ac962bd437c1e30e89406a8"),
        "average_rating" : 5,
        "total_rating" : 15
}
{
        "_id" : ObjectId("5af3d89161cc0a0e60f0925d"),
        "rating" : {
                "food" : 4,
                "service" : 5,
                "value" : 4
        },
        "restaurantID" : ObjectId("5ac962bd437c1e30e89406a8"),
        "average_rating" : 4.333333333333333,
        "total_rating" : 13
}

【讨论】:

  • 按我的预期工作。感谢您的快速回答和更多信息!
猜你喜欢
  • 2014-07-26
  • 2023-04-06
  • 2011-12-02
  • 1970-01-01
  • 2021-05-16
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多