Делайте подсчет с условием внутри функции агрегации mongDB - PullRequest
1 голос
/ 04 августа 2020

У меня есть 2 коллекции внутри моей MongoDB:

Order:
{
    "date" : ISODate("2020-07-30T22:00:00.000Z"),
    "item" : "banana",
    "price": "4$",
    "order_type" : "INTERNATIONAL", // There are 2 order types: INTERNATIONAL and MAINLAND
    "user" : {                   // I use a dbref to the User collection
        "$ref" : "user",
        "$id" : "user_0"
    }
}
 
User:
{
    "_id": "user_0"
    "login" : "user1",
    "password" : "$2a$10$mE.qmcV0mFU5NcKh73TZx.z4ueI/.bDWbj0T1BYyqP481kGGarKLG",
    "first_name" : "Henry",
    "last_name" : "Windsor",
    "email" : "hw@gmail.com",
}

Каждый заказ содержит ссылку на БД соответствующего пользователя, который его сделал. Это мой код mon go для расчета общего количества заказов, которые делает каждый пользователь.

db.getCollection('order').aggregate([
    {$group: {
        _id: '$user',
        totalNbOfOrders: {$sum: 1}
    }},
    {$addFields: {foreign_key: {$objectToArray: "$_id"}}},
    {$lookup: {
        from: 'user',
        localField: 'foreign_key.1.v',
        foreignField: '_id',
        as: 'userInfo'
        }
    },
    { $unwind: '$userInfo'},
    { $project: {
        '_id': 0,
        'first_name': '$userInfo.first_name',
        'last_name': '$userInfo.last_name',
        'totalNbOfOrders': '$totalNbOfOrders'
        }
    }
])

И результат:

    /* 1 */
    {
        "first_name" : "John",
        "last_name" : "Kennedy",
        "totalNbOfOrders" : 2.0
    }
    
    /* 2 */
    {
        "first_name" : "Peter",
        "last_name" : "Parker",
        "totalNbOfOrders" : 4.0
    }
    
    /* 3 */
    {
        "first_name" : "Bruce",
        "last_name" : "Banner",
        "totalNbOfOrders" : 2.0
    }

Теперь, что я также хочу Calculate - это количество международных заказов (и, в конечном итоге, заказов на материке), которые сделал каждый пользователь, чтобы получить что-то вроде этого:

{
    "first_name" : "Tony",
    "last_name" : "Stark",
    "totalNbOfOrders" : 10.0,
    "totalNbOfInternationalOrders": 4.0
    "totalNbOfMainlandOrders": 6.0
}

Я не понял, как написать код. Я пытался использовать оператор «$ аккумулятор» (новая функция в версии 4.4 MongoDB) внутри «$ group», но я использовал MongoDB 4.2.7, мне пришлось использовать операторы из более старых версий, чтобы выполнить sh это. Кто-нибудь знает, как решить эту проблему?

1 Ответ

1 голос
/ 04 августа 2020

Вы можете сделать это внутри $group, используя $cond и $eq,

  {
    $group: {
      ... // skipped

      // INTERNATIONAL COUNT
      totalNbOfInternationalOrders: {
        $sum: {
          $cond: {
            if: {
              $eq: ["$order_type", "INTERNATIONAL"]
            },
            then: 1,
            else: 0
          }
        }
      },

      // MAINLAND COUNT
      totalNbOfMainlandOrders: {
        $sum: {
          $cond: {
            if: {
              $eq: ["$order_type", "MAINLAND"]
            },
            then: 1,
            else: 0
          }
        }
      }
    }
  },
  • установлен в $project
  {
    $project: {
      ... // skipped

      "totalNbOfInternationalOrders": "$totalNbOfInternationalOrders",
      "totalNbOfMainlandOrders": "$totalNbOfMainlandOrders"
    }
  }

Детская площадка: https://mongoplayground.net/p/_IeVcSFt_nY

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...