从 id 数组到名称数组(mongo,nodejs)
From an array of ids to an array of names (mongo, nodejs)
我已经查了好几个小时了...感谢您的帮助。
我有一个"Users"集合,每个用户都有一个_id
和一些名字(Username
、FirstName
、LastName
)。
我还有一个"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 which I thought will solve my problem. I tried just async, async.whilst, async.times and even tried to hack something with async.waterfall - 但没有任何效果 - 几乎所有的结果都是一样的:数组在字符串被推送到它之前就被传递了。
也许我处理这个任务的方法是错误的?
您可以使用 $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
});
如果您已经有一个用户 ID 数组,那么最好使用 map()
method and then in the find()
query use the $in
运算符将该字符串数组转换为一个 ObjectId 数组,该运算符选择字段值等于指定数组中的任意值的文档。
您需要调用 toArray()
method on the find()
游标,以便您可以在数组中获取结果,进一步操作数组以 return 所需结果,类似于以下内容:
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();
});
});
另一种方法是采用聚合路由,您可以在其中使用 $group
pipeline step to create the desired array with $push
and $concat
运算符。
考虑 运行 以下聚合操作:
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();
});
});
我已经查了好几个小时了...感谢您的帮助。
我有一个"Users"集合,每个用户都有一个_id
和一些名字(Username
、FirstName
、LastName
)。
我还有一个"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 which I thought will solve my problem. I tried just async, async.whilst, async.times and even tried to hack something with async.waterfall - 但没有任何效果 - 几乎所有的结果都是一样的:数组在字符串被推送到它之前就被传递了。
也许我处理这个任务的方法是错误的?
您可以使用 $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
});
如果您已经有一个用户 ID 数组,那么最好使用 map()
method and then in the find()
query use the $in
运算符将该字符串数组转换为一个 ObjectId 数组,该运算符选择字段值等于指定数组中的任意值的文档。
您需要调用 toArray()
method on the find()
游标,以便您可以在数组中获取结果,进一步操作数组以 return 所需结果,类似于以下内容:
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();
});
});
另一种方法是采用聚合路由,您可以在其中使用 $group
pipeline step to create the desired array with $push
and $concat
运算符。
考虑 运行 以下聚合操作:
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();
});
});