Несколько групп - Усреднение каждого значения в массиве без дублирования из другого документа - PullRequest
0 голосов
/ 10 сентября 2018

Я добавил три образца данных JSON для лучшего понимания:

{
    "_id" : ObjectId("5b961bdfd6588fed3fd8e2a9"),
    "claim" : ObjectId("5b927bd9c725181a3dc9107e"),
    "user" : ObjectId("5b869a5d0d56de9d788edb7e"),
    "comprisedPhrase" : [
        {
            "phrase" : "ABC",
            "like" : 1,
            "dislike" : 0
        }, 
        {
            "phrase" : "DEF",
            "like" : 0,
            "dislike" : 1
        }, 
        {
            "phrase" : "GHI",
            "like" : 1,
            "dislike" : 0
        }
    ], 
},
{
    "_id" : ObjectId("5b961bdfd6588fed3fd8e2a9"),
    "claim" : ObjectId("5b927bd9c725181a3dc9107e"),
    "user" : ObjectId("5b869a5d0d56de9d788edb7a”),
    "comprisedPhrase" : [
        {
            "phrase" : "ABC",
            "like" : 1,
            "dislike" : 0
        }, 
        {
            "phrase" : "DEF",
            "like" : 0,
            "dislike" : 1
        }, 
        {
            "phrase" : "GHI",
            "like" : 1,
            "dislike" : 0
        }
    ], 
},
{
    "_id" : ObjectId("5b961bdfd6588fed3fd8e2a9"),
    "claim" : ObjectId("5b927bd9c725181a3dc9107a”),
    "user" : ObjectId("5b869a5d0d56de9d788edb7a”),
    "comprisedPhrase" : [
        {
            "phrase" : "ABC",
            "like" : 0,
            "dislike" : 1
        }, 
        {
            "phrase" : "DEF",
            "like" : 1,
            "dislike" : 0
        }, 
        {
            "phrase" : "GHI",
            "like" : 1,
            "dislike" : 0
        },
        {
            "phrase" : "JKL",
            "like" : 0,
            "dislike" : 0
        }
    ], 
}

Ожидаемый результат:

/* 1 */
{
    "_id" : ObjectId("5b927bd9c725181a3dc9107e"), // Claim id
    "comprisedPhrase" : [ 
        {
            "phrase" : "ABC",
            "totalCount" : 2.0,
            "sumLike" : 2,
            "sumDislike" : 0
        }, 
        {
            "phrase" : "DEF",
            "totalCount" : 2.0,
            "sumLike" : 0,
            "sumDislike" : 2
        },
        {
            "phrase" : "GHI",
            "totalCount" : 2.0,
            "sumLike" : 2,
            "sumDislike" : 0
        }
    ],
    "totalCount" : 2.0
}

/* 2 */
{
    "_id" : ObjectId("5b927bd9c725181a3dc9107a"),
    "comprisedPhrase" : [ 
        {
            "phrase" : "ABC",
            "totalCount" : 1.0,
            "sumLike" : 0,
            "sumDislike" : 1
        },
        {
            "phrase" : "DEF",
            "totalCount" : 1.0,
            "sumLike" : 1,
            "sumDislike" : 0
        },
        {
            "phrase" : "GHI",
            "totalCount" : 1.0,
            "sumLike" : 1,
            "sumDislike" : 0
        },
        {
            "phrase" : "JKL",
            "totalCount" : 1.0,
            "sumLike" : 0,
            "sumDislike" : 0
        }
    ],
    "totalCount" : 1.0
}

Что я уже пробовал:

db.getCollection(‘anydb’).aggregate([{
  {
    "$unwind": "$comprisedPhrase"
  },
  {
      "$group" : {
        _id: "$comprisedPhrase.phrase",
        claimId: { "$first" : "$claim._id"},
        totalCount: { "$sum": 1 },
        sumLike : {"$sum" : "$comprisedPhrase.like"},
        sumDislike : {"$sum" : "$comprisedPhrase.dislike"}
    }
  },{
      "$group" : {
        _id: "$claimId",
        comprisedPhrase: { "$push" : { phrase: "$_id", totalCount: "$totalCount", sumLike: "$sumLike", sumDislike: "$sumDislike" }},
        totalCount: { "$sum": 1 }
    }
  }
  ])

Но это также будет считать ABC из разных претензий. И это очевидно.

Я просто хочу сгруппировать по claim id. и для каждой заявки есть список слов. Этот список слов должен дать мне сумму like и dislike или усреднение like и dislike с внутренним значением totalCount.

Примечание: MongoDB V3.2.18

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Ваш второй этап должен сделать _id как $comprisedPhrase.phrase и $claim._id.

Таким образом, окончательный запрос должен выглядеть следующим образом:

db.getCollection(‘anydb’).aggregate([{
  {
    "$unwind": "$comprisedPhrase"
  },
  {
      "$group" : {
        _id: {"phrase": "$comprisedPhrase.phrase", "claimId":"$claim._id"},
        //claimId: { "$first" : "$claim._id"},
        totalCount: { "$sum": 1 },
        sumLike : {"$sum" : "$comprisedPhrase.like"},
        sumDislike : {"$sum" : "$comprisedPhrase.dislike"}
    }
  },{
      "$group" : {
        _id: "$_id.claimId",
        comprisedPhrase: { "$push" : { phrase: "$_id.phrase", totalCount: "$totalCount", sumLike: "$sumLike", sumDislike: "$sumDislike" }},
        totalCount: { "$sum": 1 }
    }
  }
  ])

Надеюсь, это поможет. Спасибо.

0 голосов
/ 10 сентября 2018

Вы можете попробовать ниже агрегации

db.collection.aggregate([
  { "$unwind": "$comprisedPhrase" },
  { "$group": {
    "_id": { "phrase": "$comprisedPhrase.phrase", "claimId": "$claim" },
    "sumLike": { "$sum": "$comprisedPhrase.like" },
    "sumDislike": { "$sum": "$comprisedPhrase.dislike" },
    "count": { "$sum": 1 }
  }},
  { "$group": {
    "_id": "$_id.claimId",
    "totalCount": { "$first": "$count" },
    "comprisedPhrase": {
      "$push": {
        "phrase": "$_id.phrase",
        "sumLike": "$sumLike",
        "sumDislike": "$sumDislike",
        "totalCount": "$count"
      }
    }
  }}
])
...