MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Групиране на документи в MongoDB при специално условие

Отказ от отговорност

Преди да прочетете останалата част от отговора, моля, прочетете https://docs. mongodb.com/manual/core/aggregation-pipeline-limits/ Очаква се полученият документ във въпроса да има масив от всички документи, които принадлежат към определена възрастова група.Размерът на този масив не може да надвишава 16MB , така че кодът по-долу ще работи само за много малки колекции от малки документи.

Кодът:

db.collection.aggregate([
    { $sort: { age: 1 } },
    { $group: {
            _id: null,
            ages: { $push: "$age" }
    } },
    { $addFields: {
        ranges: { $reduce: { 
            input: { $range: [ 1, { $size: "$ages" }, 1 ] }, 
            initialValue: [ [ { $arrayElemAt: [ "$ages", 0 ] } ] ], 
            in: { $cond: { 
                if:  { $gt: [
                    { $subtract: [ { $arrayElemAt: [ "$ages", "$$this" ] }, { $arrayElemAt: [ "$ages", { $subtract: [ "$$this", 1 ] } ] } ] },
                    2
                    ] }, 
                then: { $concatArrays: [ "$$value",  [ [ { $arrayElemAt: [ "$ages", "$$this" ] } ] ] ] }, 
                else: { $concatArrays: [ 
                    { $slice: [ "$$value" , { $subtract: [ { $size: "$$value" }, 1 ] } ] },
                    [ { $concatArrays: [ 
                        { $arrayElemAt: [ { $slice: [ "$$value" , -1 ] }, 0 ] }  ,  
                        [ { $arrayElemAt: [ "$ages", "$$this" ] } ]
                    ]  } ]
                ] }
            } }
        } } 
    } },
    { $unwind: "$ranges" }, 
    { $lookup: {
       from: "collection",
       localField: "ranges",
       foreignField: "age",
       as: "group"
     } },
     { $project: { _id: 0, group: 1 } }
])

Частта, която може да изисква малко обяснение, е как се изчисляват възрастовите групи.

За това получаваме всички възрасти, използвайки $group в единичен масив и след това $addFields "диапазони" - 2D масив от възрастови групи с пропуски между най-възрастния човек в по-младата група и най-младия човек в по-възрастната група е по-голям от 2 години.

Масивът се изчислява с помощта на $reduce на $range масив от индекси от всички възрасти, но първият, който отива към първоначалната стойност.

Изразът за намаляване е $cond който изчислява разликата между текущия и предишния ($subtract ) елемент от масива от всички възрасти.

Ако е по-голямо от 2, се добавя нова възрастова група с помощта на $concatArrays . В противен случай възрастта се добавя към най-старата група с помощта на $slice за насочване към последната група в масива с диапазони и $setUnion за премахване на дубликати.

Когато се изчисляват възрастовите групи, ние $lookup една и съща колекция по възраст, за да ги групирате в масива „група“.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Задайте дата по подразбиране в документа на Mongoose на сега + [известно увеличение]

  2. Mongodb група и оператори на проекти

  3. Правилен начин за вмъкване на много записи в Mongodb с Node.js

  4. как да работите с множество действия и да получите брой с помощта на mongodb?

  5. Изграждане на mongo-cxx-driver с помощта на CMake ExternalProject_Add