mongoose ref sub field

时间:2018-01-21 15:39:10

标签: node.js mongodb mongoose populate

我想通过refing到subject.book._id的子字段/ id来填充myBook.title 有可能吗?

let subject= new Schema({
     subjectTitle{
         first:String,
         last: String,
     },
     book[
         {
             title: {type: String, required: true,unique:true}
         }
     ],
})

let myBook= new Schema({
     title: {type: ObjectId, ref:'subject.book'}
})

1 个答案:

答案 0 :(得分:0)

您的代码中有一些小错误:

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) => {});