MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Czy możliwe jest grupowanie i sumowanie wielu kolumn w ramach agregacji MongoDB?

Od MongoDB 3.4 można to osiągnąć nieco prościej, używając wielu potoków agregacji z $facet .

pochodzi z dokumentacji :

Tak więc w twoim przypadku użycia można to osiągnąć w następujący sposób:

const aggregatorOpts = [
    { $match: { character: 'broquaint' } }, // Match the character
    {
        // Seperate into 2 or more pipes that will count class and
        // race seperatly
        $facet: {
            race: [
                // Group by race and get the count:
                // [
                //   {
                //     _id: 'Halfling',
                //     count: 3
                //   }
                //   {
                //     _id: 'Naga',
                //     count: 2
                //   }
                // ]

                // $sortByCount is the same as
                // { $group: { _id: <expression>, count: { $sum: 1 } } },
                // { $sort: { count: -1 } }

                { $sortByCount: '$race' },

                // Now we want to transform the array in to 1 document,
                // where the '_id' field is the key, and the 'count' is the value.
                // To achieve this we will use $arrayToObject. According the the
                // docs, we have to first rename the fields to 'k' for the key,
                // and 'v' for the value. We use $project for this:
                {
                    $project: {
                        _id: 0,
                        k: '$_id',
                        v: '$count',
                    },
                },
            ],
            // Same as above but for class instead
            class: [
                { $sortByCount: '$class' },
                {
                    $project: {
                        _id: 0,
                        k: '$_id',
                        v: '$count',
                    },
                },
            ],
        },
    },
    {
        // Now apply the $arrayToObject for both class and race.
        $addFields: {
            // Will override the existing class and race arrays
            // with their respective object representation instead.
            class: { $arrayToObject: '$class' },
            race: { $arrayToObject: '$race' },
        },
    },
];

db.races.aggregate(aggregatorOpts)

Co daje:

[
  {
    "race": {
      "Halfling": 3,
      "Naga": 2
    },
    "class": {
      "Hunter": 3,
      "Rogue": 1,
      "Fighter": 1,
    }
  }
]

Jeśli jesteś zadowolony z dostarczonego formatowania wyjściowego @Asya, możesz usunąć $project i $addFields etapy i po prostu opuść $sortByCount część w każdym podrurociągu.

Dzięki tym nowym funkcjom agregację można znacznie łatwiej rozszerzyć o dodatkowe liczniki.Wystarczy dodać kolejny potok agregacji w $facet .Jeszcze łatwiej jest policzyć podgrupy, ale to byłoby osobne pytanie.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB:wypisz „id” zamiast „_id”

  2. Sortowanie klienta mongodb findOne() w węźle

  3. Czy MongoDB i jego sterowniki mogą zachować kolejność elementów dokumentu?

  4. Pobierz dane z 2 kolekcji w mongodb w jednym zapytaniu

  5. Odczytanie DBname.system.indexes nie powiodło się w klastrze Atlas przez mongobee po uzyskaniu połączenia