Как сделать запрос только на сумму во всей коллекции?

#mongodb #mongodb-query

#mongodb #mongodb-запрос

Вопрос:

У меня есть эта коллекция

 { 
    "_id" : BinData(0, "JUw6VoBVdtqAQ2g7sn0sog=="), 
    "os_name" : "android" 
}
  

Я хочу получить в одном совокупном запросе количество документов с

 os_android => count of documents where "os_name" = "android" 
os_ios => count of documents where "os_name" = "ios"
total => the total count of document
  

Как я могу сделать?

Я пытаюсь это :

 db.getCollection("myCollection").aggregate(
[
    {$group:{
      _id:{},
      by_os_ios:{$sum:{$cond:[{os_name:"ios"},NumberInt(1),NumberInt(0)]}},
      by_os_android:{$sum:{$cond:[{os_name:"android"},NumberInt(1),NumberInt(0)]}},
      total:{$sum:1}}
    },
    {$addFields:{
      "by_os.ios":"$by_os_ios",
      "by_os.android":"$by_os_android"}},
    {$project:{
      _id:0,
      by_os_ios:0,
      by_os_android:0}}
  ]
);
  

но это не работает: ( что я пропустил?

Ответ №1:

Вы пропустили $eq $cond , вы можете проверить условие с помощью { $eq:["$field_name", "value to matched"] }

 db.getCollection("myCollection").aggregate([
  {
    $group: {
      _id: {},
      by_os_ios: { $sum: { $cond: [{ $eq: ["$os_name", "ios"] }, 1, 0] } },
      by_os_android: { $sum: { $cond: [{ $eq: ["$os_name", "android"] }, 1, 0] } },
      total: { $sum: 1 }
    }
  },
  ... // your other pipeline stages
])
  

Игровая площадка


Второй возможный способ,

  • $group для создания массива с именем root
  • $project чтобы получить количество общих документов, используя $size
  • $reduce для перебора цикла по корневому массиву и проверки условия, если его ios затем суммируется, а если его android затем суммируется с использованием $add и слияния с текущим объектом значения с помощью $mergeObjects

Игровая площадка