Nodejs + Mongodb: найти данные после агрегации

Я новичок в Nodejs и MongoDB.
Вот образец моего набора данных:

{ 
  'name': ABC,
  'age':24,
  'gender':male,
  ...
}

Вообще говоря, я хочу объединить данные, прежде чем использовать их для поиска различных кластеров данных.
Если быть точным, я хочу знать, сколько людей в разных возрастах. Затем найти людей (документы) в каждом возрасте и хранить их.

Вот мой код:

MongoClient.connect(url, function(err, db) {
    if(err) { 
        console.log('Unable to connect to the mongoDB server. Error:', err); 
    } else { 
        db.collection('test').aggregate(
        [
          { $group: { _id: "$age" , total: { $sum: 1 } } },
          { $sort: { total: -1 } } 
        ]).toArray(function(err, result) {
            assert.equal(err, null);
            age = [];
            for(var i in result) {
                age.push(result[i]['_id'])
            };
            ageNodes = {};
            for(var i in age) {
                 nodes = [];
                 var cursor = db.collection('test').find({'age':age[i]});
                 // query based on aggregated data
                 cursor.each(function(err,doc){
                    if(doc!=null){
                        nodes.push(doc);
                    } else {
                        console.log(age[i]);
                        ageNodes[age[i]] = nodes;
                    }
                })
            }
            res.json(ageNodes);
        });
    };
});

Мой ожидаемый формат JSON:

{
  age:[different documents]
}

пример:

{
  20:[{name:A,gender:male,...},{},...],
  30:[{name:B,gender:male,...},{},...],
  ...
}

Однако то, что я получил, было пустым результатом, поэтому я думаю, что, возможно, это было вызвано циклом for.
Я понятия не имею, как обрабатывать асинхронный обратный вызов.

1 ответ

Решение

Вам нужно только запустить следующий конвейер, который использует $push добавить корневой документ (представлен $$ROOT системная переменная в конвейере) в массив для возрастной группы:

Используя MongoDB 3.4.4 и новее:

MongoClient.connect(url, function(err, db) {
    if(err) { 
        console.log('Unable to connect to the mongoDB server. Error:', err); 
    } else { 
        db.collection('test').aggregate([
            { '$group': { 
                '_id': '$age', 
                'total': { '$sum': 1 }, 
                'docs': { '$push': '$$ROOT' }
            } },
            { '$sort': { 'total': -1 } },
            { '$group': {
                '_id': null,
                'data': {
                    '$push': {
                        'k': '$_id',
                        'v': '$docs'
                    }
                }
            } },
            { '$replaceRoot': {
                'newRoot': { '$arrayToObject': '$data' }
            } }    
        ]).toArray(function(err, results) {
            console.log(results);
            res.json(results);
        });
    };
});

Используя MongoDB 3.2 и ниже:

MongoClient.connect(url, function(err, db) {
    if(err) { 
        console.log('Unable to connect to the mongoDB server. Error:', err); 
    } else { 
        db.collection('test').aggregate([
            { '$group': { 
                '_id': '$age', 
                'total': { '$sum': 1 }, 
                'docs': { '$push': '$$ROOT' }
            } },
            { '$sort': { 'total': -1 } } 
        ]).toArray(function(err, results) {
            console.log(results);
            var ageNodes = results.reduce(function(obj, doc) { 
                obj[doc._id] = doc.docs
                return obj;
            }, {});
            console.log(ageNodes);
            res.json(ageNodes);
        });
    };
});
Другие вопросы по тегам