我有一台node.js(express based)
服务器,其中有一台function
返回所有users
。这是函数。
export async function findAllUser() {
let users = await User.find({}).exec()
return users
}
在我的node.js
应用程序中,我有models(schema)
和Users
中的两个Referrals
,就像这样。
var User = mongoose.model(
"users",
new Schema({
first_name: String,
last_name: String,
name: String,
email: String,
password: String,
roleId: { type: Number, default: 0 },
country: String,
token: String,
createdAt: String,
updatedAt: String,
tempToken: String,
verificationCode: String,
fbUserId: String,
isFbUser: { type: Boolean, default: false },
isActive: { type: Boolean, default: true },
isEmailVerified: { type: Boolean, default: false },
rememberme: Boolean,
}, {
toJSON: { virtuals: true },
toObject: { virtuals: true }
})
);
User.virtual("referrals", {
ref: "referralLinks",
foreignField: "userId",
localField: "_id"
});
export var ReferralLink = mongoose.model(
"referralLinks",
new Schema({
referral_link: String,
referral_code: String,
isLink: Number,
offer_name: String,
offer_desc: String,
user_email: String,
companyId: { type: Schema.Types.ObjectId, ref: 'companies' },
addedByAdmin: { type: Boolean, default: true },
number_of_clicks: Number,
referral_country: String,
link_status: String,
categoryId: { type: Schema.Types.ObjectId, ref: 'categories' },
number_of_clicks: { type: Number, default: 0 },
createdAt: String,
updatedAt: String,
userId: { type: Schema.Types.ObjectId, ref: 'users' }
})
);
我有一个单独的api.route.js
文件,在该文件中,我已让所有用户都这样路由
router.get("/", log, getAllUsers);
我的api.controller.js
文件中有getAllUsers
这样的
export async function getAllUsers(req, res) {
try {
let Users = await findAllUser()
if (Users) {
generateResponse(true, "All Users fetched", Users, res)
} else {
generateResponse(false, "No Users found", null, res)
}
} catch (err) {
generateResponse(false, 'Error occured, 404 not found!', err, res)
}
}
在我的api.handler.js
文件中,我具有findAllUser
这样的功能
export async function findAllUser() {
let users = await User.find({}).populate("referrals").exec()
return users
}
单个用户可以有多个Referrals
。但是很遗憾,我在_id
文档中没有“ Referrals”参考Users
。现在,我想让所有用户拥有各自的Referrals
我正确地获取了所有users
,但是对于每个用户,我也想获取他们各自的所有referrals
。因此,由于猫鼬查找的异步特性,我绝对不能使用for
或forEach
循环。那么我应该使用什么来代替for
或forEach
循环?
我想要的结果
results = [
{
first_name : "Fahad",
last_name : "subzwari",
email : "fahadsubzwari@gmail.com",
password : "***",
referrals : [
{
//referral object 1
},
{
//referral object 2 ...
}
]
},
{
first_name : "Alex",
last_name : "Hales",
email : "alex@gmail.com",
password : "***",
referrals : [
{
//referral object 1
},
{
//referral object 2 ...
},
{
//referral object 3 ...
}
]
},
]
答案 0 :(得分:1)
要能够访问用户的引荐,您需要使用virtual populate。
所以您的userSchema必须是这样的:
const userSchema = new Schema(
{
first_name: String,
last_name: String,
name: String,
email: String,
password: String,
roleId: { type: Number, default: 0 },
country: String,
token: String,
createdAt: String,
updatedAt: String,
tempToken: String,
verificationCode: String,
fbUserId: String,
isFbUser: { type: Boolean, default: false },
isActive: { type: Boolean, default: true },
isEmailVerified: { type: Boolean, default: false },
rememberme: Boolean
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
);
// Virtual populate
userSchema.virtual("referrals", {
ref: "referralLinks",
foreignField: "userId",
localField: "_id"
});
var User = mongoose.model("users", userSchema);
现在您可以使用此路由来访问用户的引荐:
router.get("/", async (req, res) => {
const result = await User.find({}).populate("referrals");
res.send(result);
});
结果将是这样的:(为简单起见,我排除了一些字段)
[
{
"_id": "5dd6819201419f5930d02334",
"name": "User 1",
"email": "user1@gmail.com",
"password": "123123",
"__v": 0,
"referrals": [
{
"_id": "5dd6829831b95a6b2cd58fca",
"referral_link": "referral_link 1",
"userId": "5dd6819201419f5930d02334",
"__v": 0
},
{
"_id": "5dd682a031b95a6b2cd58fcb",
"referral_link": "referral_link 2",
"userId": "5dd6819201419f5930d02334",
"__v": 0
}
],
"id": "5dd6819201419f5930d02334"
},
{
"_id": "5dd681a101419f5930d02335",
"name": "User 2",
"email": "user2@gmail.com",
"password": "123123",
"__v": 0,
"referrals": [
{
"_id": "5dd682a731b95a6b2cd58fcc",
"referral_link": "referral_link 3",
"userId": "5dd681a101419f5930d02335",
"__v": 0
}
],
"id": "5dd681a101419f5930d02335"
}
]
更新:
这是您的项目设置步骤:
api.handler.js:
exports.findAllUser = async function() {
console.log("api handler inside");
let users = await User.find({})
.populate("referrals")
.exec();
console.log("in handler: ", users);
return users;
};
api.controller.js:
const handler = require("./api.handler");
exports.getAllUsers = async function(req, res) {
console.log("userController.getAllUsers");
try {
let Users = await handler.findAllUser();
if (Users) {
return res.send(Users);
generateResponse(true, "All Users fetched", Users, res);
} else {
generateResponse(false, "No Users found", null, res);
}
} catch (err) {
generateResponse(false, "Error occured, 404 not found!", err, res);
}
};
api.route.js
const apiController = require("../controllers/api.controller");
router.get("/", log, apiController.getAllUsers);
答案 1 :(得分:0)
您说“我在用户中没有'Referrals'引用_id”,所以我假设您在Referrals模式中具有对该用户的引用?
否则,由于无法链接它们,您恐怕迷路了...:-(
如果这样做,则可以在一个单独的查询中进行:
const userIds = users.map(user => user._id);
const referrals = await Referrals.find({ userId: { $in: userIds } })
$ in运算符将获取数组中包含用户ID的任何字段。
编辑:响应您的更新-是的,上面应该可以正常工作。然后,您可以对他们进行所需的操作,例如将引荐映射到用户对象,或单独使用它们,等等。
EDIT2:是的,这就是方法。此时,您拥有一系列用户和一个引荐来源,因此您只需要将它们组合在一起。
users.map(user => ({
// add props from user obj
...user,
// add all referrals that with matching userId
referrals: referrals.filter(referral => referral.userId === user._id)
}))
请记住,在处理异步调用和承诺时,您将需要使用async / await关键字,或者在promise回调中解析结果。