最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - From an array of ids to an array of names (mongo, nodejs) - Stack Overflow

programmeradmin1浏览0评论

I've been poking around this for several hours... Thanks for any help.

I have a "Users" collection, each user has an _id and some names (Username, FirstName, LastName). I also have a "Group" collection, each group has Members, which is an array of users' _id.

At first I wanted a simple function that receives an array of ids and turns it into an array of strings in a nice format: FirstName + " " + LastName + " (" + Username + ")". So I made a simple for for that:

    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 + ")";
        });
    }

But since mongo is async that didn't work. After some reading, I installed async which I thought will solve my problem. I tried just async, async.whilst, async.times and even tried to hack something with async.waterfall - but nothing worked - pretty much all ended the same way: the array was passed before the strings were push to it.

Maybe my approach to this task is wrong?

I've been poking around this for several hours... Thanks for any help.

I have a "Users" collection, each user has an _id and some names (Username, FirstName, LastName). I also have a "Group" collection, each group has Members, which is an array of users' _id.

At first I wanted a simple function that receives an array of ids and turns it into an array of strings in a nice format: FirstName + " " + LastName + " (" + Username + ")". So I made a simple for for that:

    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 + ")";
        });
    }

But since mongo is async that didn't work. After some reading, I installed async which I thought will solve my problem. I tried just async, async.whilst, async.times and even tried to hack something with async.waterfall - but nothing worked - pretty much all ended the same way: the array was passed before the strings were push to it.

Maybe my approach to this task is wrong?

Share Improve this question asked Dec 30, 2015 at 18:12 Yogev LevyYogev Levy 3353 silver badges16 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

If you already have an array of user ids then it would be best if you convert that string array to an array of ObjectIds using the map() method and then in the find() query use the $in operator which selects the documents where the value of a field equals any value in the specified array.

You would need to call the toArray() method on the find() cursor so that you can get the results in an array, further manipulate the array to return the desired result, something like the following:

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();
         });  
});

Another approach is taking the aggregate route in which you can use the $group pipeline step to create the desired array with $push and $concat operators.

Consider running the following aggregate operation:

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();
    });  
});

You can use the $in operator to find multiple users with a single query. This is both better for performance and less hassle with asynchronicity.

// 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
});
发布评论

评论列表(0)

  1. 暂无评论