Aggregate, Mongoose - игнорирует дублированные результаты - PullRequest
0 голосов
/ 10 мая 2018

У меня есть следующая схема

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 } ]

1 Ответ

0 голосов
/ 10 мая 2018

Не $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
}
...