我有一个相当简单的问题。我试图保存其架构包含嵌套架构引用的文档,并且该架构引用包括另一个架构引用。但是,当我去检索该文档时,它不包括(必需的)嵌套字段,除非我在同一查询中填充它。但是,即使填充查询,也不会填充第二个嵌套文档。我是否误解了关于在mongoose中使用refs的方式的基本内容?
下面的JavaScript和LiveScript示例代码和输出。
(function(){
var mongoose, bookSchemaObj, authorSchemaObj, agentSchemaObj, bookSchema, authorSchema, agentSchema, Book, Author, Agent, testBookObj, testAuthorObj, testAgentObj, testAgent, testAuthor, testBook;
mongoose = require("mongoose-bird")(require("mongoose"));
mongoose.connect("mongodb://test:test@localhost:27017/test");
bookSchemaObj = {
author: {
type: mongoose.Schema.Types.ObjectId,
ref: "Author",
required: true
},
pubYear: {
type: Number
}
};
authorSchemaObj = {
name: {
type: String,
required: true
},
agent: {
type: mongoose.Schema.Types.ObjectId,
ref: "Agent",
required: true
}
};
agentSchemaObj = {
name: {
type: String,
required: true
}
};
bookSchema = new mongoose.Schema(bookSchemaObj);
authorSchema = new mongoose.Schema(authorSchemaObj);
agentSchema = new mongoose.Schema(agentSchemaObj);
Book = mongoose.model("Book", bookSchema);
Author = mongoose.model("Author", authorSchema);
Agent = mongoose.model("Agent", agentSchema);
testBookObj = {
pubYear: 2001
};
testAuthorObj = {
name: "John P. Doe"
};
testAgentObj = {
name: "Alfred O. Thompson"
};
testAgent = new Agent(testAgentObj);
testAuthor = new Author(testAuthorObj);
testBook = new Book(testBookObj);
testAuthor.agent = testAgent._id;
testBook.author = testAuthor._id;
testAgent.saveAsync().then(function(){
return testAuthor.saveAsync();
}).then(function(){
return testBook.saveAsync();
}).then(function(){
console.log("book after saving agent, author, and book:");
console.log(JSON.stringify(testBook, undefined, 2));
console.log("");
return Author.findById(testAuthor._id).populate("agent").execAsync();
}).then(function(queriedAuthor){
console.log("author after finding and populating author");
console.log(JSON.stringify(queriedAuthor, undefined, 2));
console.log("");
return Book.findById(testBook._id).populate("author author.agent").execAsync();
}).then(function(queriedBook){
console.log("book after finding and populating book: ");
console.log(JSON.stringify(queriedBook, undefined, 2));
console.log("");
return Book.findByIdAsync(testBook._id);
}).then(function(foundBooks){
console.log("book after finding book:");
console.log(JSON.stringify(foundBooks, undefined, 2));
console.log("");
return foundBooks.populateAsync("author");
}).then(function(populatedBook){
console.log("book after populating book: ");
console.log(JSON.stringify(populatedBook, undefined, 2));
process.exit();
})['catch'](function(err){
console.log(err);
});
}).call(this);
mongoose = require("mongoose-bird")(require("mongoose"))
mongoose.connect "mongodb://test:test@localhost:27017/test"
bookSchemaObj =
author:
type: mongoose.Schema.Types.ObjectId
ref: "Author"
required: true
pubYear:
type: Number
authorSchemaObj =
name:
type: String
required: true
agent:
type: mongoose.Schema.Types.ObjectId
ref: "Agent"
required: true
agentSchemaObj =
name:
type: String
required: true
bookSchema = new mongoose.Schema bookSchemaObj
authorSchema = new mongoose.Schema authorSchemaObj
agentSchema = new mongoose.Schema agentSchemaObj
Book = mongoose.model "Book", bookSchema
Author = mongoose.model "Author", authorSchema
Agent = mongoose.model "Agent", agentSchema
testBookObj =
pubYear: 2001
testAuthorObj =
name: "John P. Doe"
testAgentObj =
name: "Alfred O. Thompson"
testAgent = new Agent testAgentObj
testAuthor = new Author testAuthorObj
testBook = new Book testBookObj
testAuthor.agent = testAgent._id
testBook.author = testAuthor._id
testAgent.saveAsync!
.then ->
return testAuthor.saveAsync!
.then ->
return testBook.saveAsync!
.then ->
console.log "book after saving agent, author, and book:"
console.log JSON.stringify testBook, undefined, 2
console.log ""
return Author.findById(testAuthor._id).populate("agent").execAsync!
.then (queriedAuthor) ->
console.log "author after finding and populating author"
console.log JSON.stringify queriedAuthor, undefined, 2
console.log ""
return Book.findById(testBook._id).populate("author author.agent")
.execAsync!
.then (queriedBook) ->
console.log "book after finding and populating book: "
console.log JSON.stringify queriedBook, undefined, 2
console.log ""
return Book.findByIdAsync testBook._id
.then (foundBooks) ->
console.log "book after finding book:"
console.log JSON.stringify foundBooks, undefined, 2
console.log ""
return foundBooks.populateAsync "author"
.then (populatedBook) !->
console.log "book after populating book: "
console.log JSON.stringify populatedBook, undefined, 2
process.exit!
.catch (err) !->
console.log err
book after saving agent, author, and book:
{
"__v": 0,
"author": "553a52d4cd8d2a4f5a5c4185",
"pubYear": 2001,
"_id": "553a52d4cd8d2a4f5a5c4186"
}
author after finding and populating author
{
"_id": "553a52d4cd8d2a4f5a5c4185",
"agent": {
"_id": "553a52d4cd8d2a4f5a5c4184",
"name": "Alfred O. Thompson",
"__v": 0
},
"name": "John P. Doe",
"__v": 0
}
book after finding and populating book:
{
"_id": "553a52d4cd8d2a4f5a5c4186",
"author": {
"_id": "553a52d4cd8d2a4f5a5c4185",
"name": "John P. Doe",
"__v": 0
},
"pubYear": 2001,
"__v": 0
}
book after finding book:
{
"_id": "553a52d4cd8d2a4f5a5c4186",
"pubYear": 2001,
"__v": 0
}
book after populating book:
{
"_id": "553a52d4cd8d2a4f5a5c4186",
"pubYear": 2001,
"__v": 0
}
答案 0 :(得分:1)
通过无限地调用
Model.populate
ad来填充跨越2个集合的结构,可以实现多级深度引用的递归填充。
如果是多级深度引用,则多个填充populate("author author.agent")
不起作用。您必须首先填充author
,然后在author.agent
上填充Agent
。
如果您不知道要填充其ID的代理,findById并填充作者,则使用范围之外的范围的变量来存储填充的代理ID,然后重新添加它,然后填充代理。填充。
var agentId = null;
testAgent.saveAsync().then(function(){
return testAuthor.saveAsync();
}).then(function(){
return testBook.saveAsync();
}).then(function(){
return Author.findById(testAuthor._id).populate("agent").execAsync!
}).then(function(populatedAuthor){
console.log("book after saving agent, author, and book:");
console.log(JSON.stringify(testBook, undefined, 2));
console.log("");
agentId = populatedAuthor.agent._id;
return Book.findById(testBook._id).populate("author").execAsync();
}).then(function(partiallyPopulatedBook){
console.log("author after finding and populating author:");
console.log(JSON.stringify(partiallyPopulatedBook, undefined, 2));
console.log("");
partiallyPopulatedBook.author.agent = agentId;
return Agent.populate(partiallyPopulatedBook, {path:"author.agent"});
}).then(function(populatedBook){
console.log("author after finding and populating author and autho.agent:");
console.log(JSON.stringify(populatedBook, undefined, 2));
process.exit();
})['catch'](function(err){
console.log(err);
});