mo_*_*aat 1 mongoose node.js mongoose-populate mongoose-schema
不确定这是否会被视为重复,但我已经四处搜索并实现了与我在网上找到的类似查询,但似乎无法让我的嵌套引用起作用。我只是测试以了解用于填充嵌套引用和嵌套文档的猫鼬语法,如下所述:猫鼬嵌套模式与嵌套模型
但是,我一定错过了一些东西,因为它似乎可以工作,但返回一个空的嵌套引用数组。我知道我的查询应该返回嵌套引用的两个结果。
数据:
结果收集:
{
"_id" : ObjectId("5a4dcbe4ab9a793d888c9396"),
"event_id" : ObjectId("5a482302a469a068edc004e3"),
"event_name" : "Sample Event",
"score" : "3-2",
"winner" : "player1"
},
{
"_id" : ObjectId("5a59791379cc1c321c1918f0"),
"event_id" : ObjectId("5a482302a469a068edc004e3"),
"event_name" : "Sample Event",
"score" : "2-1",
"winner" : "player2"
}
Run Code Online (Sandbox Code Playgroud)
活动合集:
{
"_id" : ObjectId("5a482302a469a068edc004e3"),
"type" : "Tournament",
"name" : "Sample Event"
}
Run Code Online (Sandbox Code Playgroud)
我的代码如下:
var mongoose = require("mongoose");
mongoose.connect("MongoDB://localhost/devDB");
var ResultSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
event_id: {type: mongoose.Schema.Types.ObjectId, ref: "EventModel"},
event_name: String,
score: String,
winner: String
});
var ResultModel = mongoose.model("results", ResultSchema);
var EventSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
type: String,
results: [{type: mongoose.Schema.Types.ObjectId, ref: "ResultModel"}]
});
var EventModel = mongoose.model("events", EventSchema);
function GetEvent(eventid){
// EventModel.findById(eventid)
EventModel.findOne({_id: eventid})
.populate("results","score winner", ResultModel)
//.select("results") to extract only the nested references
.exec(function(err, event){
if (err){
console.log("ERROR fetching doc: ", err.name + ": " + err.message)
} else{
console.log(event);
}
});
}
GetEvent("5a482302a469a068edc004e3");
Run Code Online (Sandbox Code Playgroud)
我运行时的输出:
{
results: [],
_id: 5a482302a469a068edc004e3,
type: 'Tournament',
name: 'Test Tournament'
}
Run Code Online (Sandbox Code Playgroud)
您的代码的问题在于您的results数组缺少填充该数组所需的 ObjectId。您当前正在将集合与event_id结果文档连接在一起。他们引用事件集合中的文档。但是,当您对事件集合进行填充时,它希望引用位于数组中results。
以这些值为例:
结果:
{
"_id" : ObjectId("5a5be9a4669365067f984acb"),
"event_name" : "Game 1",
"score" : "1-2",
"winner" : "ManU",
"event_id" : ObjectId("5a5be9d9669365067f984acd")
}
{
"_id" : ObjectId("5a5be9b5669365067f984acc"),
"event_name" : "Game 2",
"score" : "3-2",
"winner" : "Bayern Munich",
"event_id" : ObjectId("5a5be9d9669365067f984acd")
}
Run Code Online (Sandbox Code Playgroud)
活动:
{
"_id" : ObjectId("5a5be9d9669365067f984acd"),
"name" : "Champions League",
"type" : "Cup",
"results" : [
ObjectId("5a5be9a4669365067f984acb"),
ObjectId("5a5be9b5669365067f984acc")
]
}
Run Code Online (Sandbox Code Playgroud)
我已经使用 MongoDB shell 手动插入了文档。请注意,结果文档的 objectId 存储在results数组中。如果我现在运行这段代码:
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/devDB");
const ResultSchema = mongoose.Schema({
event_id: {type: mongoose.Schema.Types.ObjectId, ref: "events"},
event_name: String,
score: String,
winner: String
});
const Results = mongoose.model("results", ResultSchema);
const EventSchema = mongoose.Schema({
name: String,
type: String,
results: [{type: mongoose.Schema.Types.ObjectId, ref: "results"}]
});
const Events = mongoose.model("events", EventSchema);
function GetEvent(eventid){
Events.findOne({_id: eventid})
.populate("results", "score winner")
.exec(function(err, event){
if (err){
console.log("ERROR fetching doc: ", err.name + ": " + err.message)
} else{
console.log(event);
}
});
}
GetEvent("5a5be9d9669365067f984acd");
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
{ _id: 5a5be9d9669365067f984acd,
name: 'Champions League',
type: 'Cup',
results:
[ { _id: 5a5be9a4669365067f984acb, score: '1-2', winner: 'ManU' },
{ _id: 5a5be9b5669365067f984acc,
score: '3-2',
winner: 'Bayern Munich' } ] }
Run Code Online (Sandbox Code Playgroud)
显示填充的结果是因为该results数组实际上包含对结果对象的引用。populate 方法在其中查找文档的集合在 中给出ref。那里的值是注册模型的名称,即您作为第一个参数给出的名称mongoose.model()。
您还可以在结果文档中使用event_id. 您问题中的代码实际上并不需要它,但如果您想双向连接(结果 <--> 事件),则可以保留它。然后你可以创建一个像这样的函数:
function GetResult(resultid){
Results.findOne({_id: resultid})
.populate("event_id", "name type")
.exec(function(err, result){
if (err){
console.log("ERROR fetching doc: ", err.name + ": " + err.message)
} else{
console.log(result);
}
});
}
Run Code Online (Sandbox Code Playgroud)
当这样执行时
GetResult("5a5be9b5669365067f984acc");
Run Code Online (Sandbox Code Playgroud)
它会给我们这个结果:
{ _id: 5a5be9b5669365067f984acc,
event_name: 'Game 2',
score: '3-2',
winner: 'Bayern Munich',
event_id:
{ _id: 5a5be9d9669365067f984acd,
name: 'Champions League',
type: 'Cup' } }
Run Code Online (Sandbox Code Playgroud)
对于嵌套模型(嵌入),您不再将 objectId 存储到文档中的其他集合中。您可以将整个文档存储为子文档。以这段代码为例:
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/devDB");
const ResultSchema = mongoose.Schema({
event_name: String,
score: String,
winner: String
});
// Don't register subdocuments!
// const Results = mongoose.model("results", ResultSchema);
const EventSchema = mongoose.Schema({
name: String,
type: String,
results: [ResultSchema]
});
const Events = mongoose.model("events", EventSchema);
function GetEvent(eventid){
Events.findOne({_id: eventid})
// We no longer use populate.
// .populate("results", "score winner")
.exec(function(err, event){
if (err){
console.log("ERROR fetching doc: ", err.name + ": " + err.message)
} else{
console.log(event);
}
});
}
GetEvent("5a5bf133669365067f984ace");
Run Code Online (Sandbox Code Playgroud)
我们现在将整个结果模式存储在事件模式中。在这种特殊情况下,它是一个数组,但不一定是。结果集合将不再存在。结果存储在事件文档本身中。确保您没有注册子文档架构。拥有它也没有意义,event_id所以我删除了它。
我使用 MongoDB shell 重新插入数据:
{
"_id" : ObjectId("5a5bf133669365067f984ace"),
"name" : "Champions League",
"type" : "Cup",
"results" : [
{
"event_name" : "Game 1",
"score" : "3-2",
"winner" : "ManU"
},
{
"event_name" : "Game 2",
"score" : "1-2",
"winner" : "Real Madrid"
}
]
}
Run Code Online (Sandbox Code Playgroud)
当我使用时GetEvents("5a5bf133669365067f984ace")我得到:
{ _id: 5a5bf133669365067f984ace,
name: 'Champions League',
type: 'Cup',
results:
[ { event_name: 'Game 1', score: '3-2', winner: 'ManU' },
{ event_name: 'Game 2', score: '1-2', winner: 'Real Madrid' } ] }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2565 次 |
| 最近记录: |