MongoDB 两个关系 collections by ID 同 Express
MongoDB relation between two collections by ID with the Express
我在建立两个 collection 之间的关系时遇到问题(我使用的是 MEAN 堆栈)
我有两个 collection:书籍和作者
在前端,我想制作一个 CRUD 菜单,在 table 中添加一本新书,然后从那里插入一些关于书的数据,然后从下拉菜单中选择作者 (fetchin来自作者的数据 collection)
所以最后我的书 collection 需要一些关于这本书的数据,然后在 object 里面我需要一组关于那些作者的数据。
书籍架构:
const BookSchema = new mongoose.Schema({
owner: { type: String, required: true },
pagesNo: { type: String, required: true },
releaseDate: { type: String, required: true },
country: { type: String, required: true },
authorID: { type: String, required: true }, <-- HERE I NEED DATA ABOUT AUTHOR
});
作者架构:
const AuthorSchema = new mongoose.Schema({
name: { type: String, required: true },
surname: { type: String, required: true },
dateOfBirth: { type: String, required: true },
countryOfBirth: { type: String, required: true },
});
预定路线:book.ts
router.get("/", async (req, res) => {
try {
const books= await Book.find();
let Author = await Author.find({
books: { $elemMatch: { _id: books.bookID } },
});
res.status(200).json(books);
} catch (err) {
res.status(404).json({ success: false, msg: "Booknot found" });
}
});
问题出在 find() 函数的某处。这是否是一个好的做法?我希望它可以处理大量数据。
感谢大家!
你好。
AuthorID 应该是 ObjectId 类型,而不是字符串。
要加入来自其他 table 的数据,您必须使用 aggregate with a lookup。
let author = await Author.aggregate([
{
$lookup:
{
from: "books",
localField: "_id",
foreignField: "authorID",
as: "books"
}
}
]);
您的 Book 架构将如下所示:
const MongooseSchema = new mongoose.Schema({
owner: {
type: String,
required: true,
},
pagesNo: {
type: String,
required: true,
},
releaseDate: {
type: String,
required: true,
},
country: {
type: String,
required: true,
},
authorId: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
});
并且您的作者架构将保持不变(以便 link 两个架构)。
你的路线是这样的(如果你想搜索所有的书连同他们的名字):
router.get('/', async (req, res) => {
try {
const books = await Book.find().populate('authorId');
res.status(200).json(books);
} catch (err) {
res.status(404).json({ success: false, msg: 'Booknot found' });
}
});
如果您想搜索具有特定作者 ID 的书籍,那么您的路线将是这样的:
router.get('/', async (req, res) => {
try {
const books = await Book.find({ authorId }).populate('authorId');
res.status(200).json(books);
} catch (err) {
res.status(404).json({ success: false, msg: 'Booknot found' });
}
});
我在建立两个 collection 之间的关系时遇到问题(我使用的是 MEAN 堆栈) 我有两个 collection:书籍和作者
在前端,我想制作一个 CRUD 菜单,在 table 中添加一本新书,然后从那里插入一些关于书的数据,然后从下拉菜单中选择作者 (fetchin来自作者的数据 collection)
所以最后我的书 collection 需要一些关于这本书的数据,然后在 object 里面我需要一组关于那些作者的数据。
书籍架构:
const BookSchema = new mongoose.Schema({
owner: { type: String, required: true },
pagesNo: { type: String, required: true },
releaseDate: { type: String, required: true },
country: { type: String, required: true },
authorID: { type: String, required: true }, <-- HERE I NEED DATA ABOUT AUTHOR
});
作者架构:
const AuthorSchema = new mongoose.Schema({
name: { type: String, required: true },
surname: { type: String, required: true },
dateOfBirth: { type: String, required: true },
countryOfBirth: { type: String, required: true },
});
预定路线:book.ts
router.get("/", async (req, res) => {
try {
const books= await Book.find();
let Author = await Author.find({
books: { $elemMatch: { _id: books.bookID } },
});
res.status(200).json(books);
} catch (err) {
res.status(404).json({ success: false, msg: "Booknot found" });
}
});
问题出在 find() 函数的某处。这是否是一个好的做法?我希望它可以处理大量数据。
感谢大家! 你好。
AuthorID 应该是 ObjectId 类型,而不是字符串。
要加入来自其他 table 的数据,您必须使用 aggregate with a lookup。
let author = await Author.aggregate([
{
$lookup:
{
from: "books",
localField: "_id",
foreignField: "authorID",
as: "books"
}
}
]);
您的 Book 架构将如下所示:
const MongooseSchema = new mongoose.Schema({
owner: {
type: String,
required: true,
},
pagesNo: {
type: String,
required: true,
},
releaseDate: {
type: String,
required: true,
},
country: {
type: String,
required: true,
},
authorId: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
});
并且您的作者架构将保持不变(以便 link 两个架构)。
你的路线是这样的(如果你想搜索所有的书连同他们的名字):
router.get('/', async (req, res) => {
try {
const books = await Book.find().populate('authorId');
res.status(200).json(books);
} catch (err) {
res.status(404).json({ success: false, msg: 'Booknot found' });
}
});
如果您想搜索具有特定作者 ID 的书籍,那么您的路线将是这样的:
router.get('/', async (req, res) => {
try {
const books = await Book.find({ authorId }).populate('authorId');
res.status(200).json(books);
} catch (err) {
res.status(404).json({ success: false, msg: 'Booknot found' });
}
});