您的代码中有一些小错误:
const Subject = new Schema({
subjectTitle: {
first:String,
last: String
},
book: [
{
title: {type: String, required: true, unique:true}
}
],
});
const MyBook = new Schema({
title: {type: ObjectId, ref:'Subject.book'}
});
但是,我非常不确定 Subject.book 可以在这里工作,因为我从未尝试过引用文档的一部分。请确保以正确的方式引用文档的子部分。否则,我建议您将文档拆分为两个不同的文档并在 Subject 的架构中引用它。
另外,如果 Subject 架构中的 book 字段中的对象将只包含一个字段,为了简单起见,最好将其删除,并使其如下所示:
book: [
{type: String, required: true, unique:true}
]
现在是您问题的答案。从MyBook 获取文档时,您可以将标题字段填充为:
MyBook.find({/*criteria here*/}).populate('title').exec((error, mybooks) => {
if (error) //handle error
console.log(mybooks[0].title);
});
请注意,我使用了mybooks[0],因为find() 方法返回一个文档数组,即使您的条件将返回单个文档,它也会被包装在一个数组中。
同样,上述console.log() 语句的输出将是一个包含标题字段及其字符串值的对象数组。或者简单的字符串数组,如果你按照我的建议简化它。
编辑:重构模型设计
据我研究,文档的子部分不能在您尝试这样做时被引用。
因此,您可以按如下方式分解您的模型设计,以实现您想要做的事情。
const BookSchema = new Schema({
title: {
type: String,
required: true,
unique:true
}
// any other book property goes here.
});
const SubjectSchema = new Schema({
subjectTitle: {
first:String,
last: String
},
book: [
{
type: ObjectId,
ref: 'Book'
}
]
});
所以现在您有一个包含每本书详细信息的图书收藏和主题收藏,其中每个主题可以拥有许多您想要的图书以及其他属性。
获取包含所有书籍的主题:
Subject.find({/*criteria here*/}).populate('book').exec((error, subjects) => {
if (error) //handle error
console.log(subjects[0].title);
});
然后找一本书:
Book.find({/*criteria goes here*/}).exec((error, book) => {});