从一组id到一组名称(mongo,nodejs)

时间:2015-12-30 18:12:24

标签: javascript node.js mongodb asynchronous async.js

我一直在探索这个问题几个小时......感谢您的帮助。

我有一个"用户"集合中,每个用户都有一个_id和一些名称(UsernameFirstNameLastName)。 我还有一个" Group"集合中,每个组都有Members,这是一组用户' _id

起初我想要一个简单的函数,它接收一个id数组并将它变成一个很好的格式的字符串数组:FirstName + " " + LastName + " (" + Username + ")"。所以我为此做了一个简单的for

    var ans = [];
    for (i=0; i<arrOfIds.length; i++) {
        users.find({"_id": ObjectID(arrOfIds[i])}, function(err, result){
            ans.push = result.FirstName + result.LastName + "(" + result.Username + ")";
        });
    }

但是因为mongo是异步的,所以没有用。经过一些阅读,我安装了async,我认为这将解决我的问题。我尝试过异步,async.whilstasync.times,甚至尝试用async.waterfall来破解 - 但没有任何效果 - 几乎都以相同的方式结束:数组在字符串被推送之前传递它。

也许我对这项任务的态度是错误的?

2 个答案:

答案 0 :(得分:4)

如果您已经有一个用户ID数组,那么最好使用 map() 方法将该字符串数组转换为ObjectIds数组,然后在{{3查询使用 find() 运算符,该运算符选择字段值等于指定数组中任何值的文档。

您需要在 $in 光标上调用 toArray() 方法,以便您可以在数组中获取结果,进一步操作要返回所需结果的数组,如下所示:

var MongoClient = require('mongodb').MongoClient,
    ObjectID = require('mongodb').ObjectID;
MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {
    // Get users collection
    var Users = db.collection('users');

    // Retrieve all the documents in the collection
    Users.find({ "_id": { "$in": arrOfIds.map(ObjectID) } })
         .toArray().then(function(users) {
             // Create array of names
             var ans = users.map(function (u){
                 return u.FirstName + " " + u.LastName + " (" + u.Username + ")";       
             });

             // Do something with the result
             console.log(ans);
             db.close();
         });  
});

另一种方法是采用汇总路线,您可以使用 find() 管道步骤创建所需的数组 $group 和< strong> $push 运营商。

考虑运行以下聚合操作:

var MongoClient = require('mongodb').MongoClient,
    ObjectID = require('mongodb').ObjectID;
MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {
    // Get users collection
    var Users = db.collection('users');

    // Retrieve all the documents in the collection
    Users.aggregate([
        { "$match": { "_id": { "$in": arrOfIds.map(ObjectID) } } },
        { "$group": {
            "_id": null,
            "users": { 
                "$push": {
                    "$concat": ["$FirstName", " ", "$LastName", " (", "$Username", ")"]
                }
            }
        } }
    ]).toArray().then(results => {

        const ans = results[0].users;

        // Do something with the result
        console.log(ans);
        db.close();
    });  
});

答案 1 :(得分:3)

您可以使用$in operator通过单个查询查找多个用户。这对性能更好,对异步性更少麻烦。

// Convert the list of ids to mongo object ids
var objectIds = arrOfIds.map(function(item) {
  return ObjectId(item);
});

// Use the $in operator to find multiple users by id
users.find({ "_id": { $in: objectIds } }, function(err, result) {
  // result is now a list of users
});