问题描述
在猫鼬中,我现在像猫鼬文档一样建立关系,我想要一个对象数组
对象是我们拥有的对象的子对象
例如在推特中,一个用户有很多推文,每条推文都有标题、内容和作者
有人给了我们用户ID,我们给了他所有推文用户的标题和内容的数组
[
{title: 'title01',content: 'aaaaaa'},{title: 'title02',content: 'bbbbb'},.
.
.
]
我试试
const username = req.params.username;
User.find({ username: username },(err,docs) => {
if (err) return res.json({ err: true });
if (docs.length > 0) {
let lives: Array<Object> = [];
docs[0].lives.forEach((live,idx) => {
Live.find({ _id: live },docs) => {
lives.push(docs[0]);
});
});
} else {
return res.json({ err: true });
}
});
lives 有标题内容和作者(在 DB 中我将其命名为 user) 但是因为 aSync,我无法在 forEach 之后获得生命 :)
更新:
实时架构:
const schema = new mongoose.Schema({
title: {
type: String,required: true,},content: {
type: String,user: {
type: mongoose.Schema.Types.ObjectId,ref: "users",});
用户架构:
import { ArraySortOptions } from "joi";
import mongoose,{ Model } from "mongoose";
interface IUser extends mongoose.Document {
email: string;
username: string;
password: string;
lives: Array<mongoose.Schema.Types.ObjectId>;
}
const schema: mongoose.Schema = new mongoose.Schema({
username: {
type: String,password: {
type: String,email: {
type: String,lives: [
{
type: mongoose.Schema.Types.ObjectId,ref: "lives",],});
const User: Model<IUser> = mongoose.model("users",schema);
export default User;
解决方法
我会做这样的事情:
const username = req.params.username;
User.find({ username: username },async (err,docs) => {
if (err) return res.json({ err: true });
if (docs.length > 0) {
// start with asnyc queries
let livePromises = [];
for (let live of docs[0].lives) {
// push new promise which resolves the docs[0] of this live id
livePromises.push(new Promise(resolve => {
Live.find({ _id: live },(err,docs) => {
resolve(docs[0]);
});
}
}
// await all query results parallel
let lives = await Promise.all(livePromises);
// use lives variable as you want
return res.json({ lives: lives });
} else {
return res.json({ err: true });
}
});
我不确定您使用的是哪种类型的系统(您写的是 lives: Array<Object>
),所以我跳过了它。根据您的喜好调整我的建议。
如果您对此答案或一般性的 Promises 有任何疑问,请发表评论。
最好使用 Mongoose 的内置 populate()
方法,它允许您引用其他集合中的文档,类似于 MongoDB 版本 >= 3.2 中的类似联接的 $lookup
聚合运算符。
由于 populate()
需要一个查询来附加自身,因此使用 User.findOne()
查询与我们在参数中提供的用户名匹配的单个用户。
使用 async/await 可以按如下方式完成:
const { username } = req.params;
const user = await User.findOne({ username }).populate('lives');
console.log(user.lives); // ---> [{title: 'title01',content: 'aaaaaa'},{ ... }]