下記の様なDriverモデルがPositionモデルを所有している。
m_driver.js
"use strict";
const mongoose = require("mongoose");
const Position = require("./m_position.js");
const Schema = mongoose.Schema;
const driverSchema = Schema({
name: {
type: String,
position: {
type: Schema.Types.ObjectId, //外部キー
ref: "Position" //参照モデル
}
});
module.exports = mongoose.model("Driver", driverSchema);
m_position.js
"use strict";
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const positionSchema = Schema({
longitude_k_x: Number,
latitude_i_y: Number,
driver: {
type: Schema.Types.ObjectId, //外部キー
ref: "Driver" //参照モデル
}
});
module.exports = mongoose.model("Position", positionSchema);
今下記のようなデータがあります。
Positionモデルデータ
{
"_id":"5ff163eb514e011e79ccc284",
"latitude_i_y":1,
"longitude_k_x":1,
"driver":"5ff163eb514e011e79ccc283",
"__v":0
}
Driverモデルのデータ
{
"_id":"5ff163eb514e011e79ccc283",
"name":"driverTaro",
"position":"5ff163eb514e011e79ccc284",
"__v":0
}
お互いに外部キーで結びついている状態です。
この状態で以下のようなpopulateメソッドを実施しました。
position.findOne({ latitude_i_y: 1 })
.populate("Driver")
.exec((error, data) => {
console.log(data);
console.log(data.driver.name);
})
結果
//console.log(data);
{
_id: 5ff163eb514e011e79ccc284,
latitude_i_y: 1,
longitude_k_x: 1,
driver: 5ff163eb514e011e79ccc283,
__v: 0
}
//console.log(data.driver.name);
undefined
求める結果
//console.log(data);
{
_id: 5ff163eb514e011e79ccc284,
latitude_i_y: 1,
longitude_k_x: 1,
driver: {
_id: 5ff163eb514e011e79ccc283,
name: 'driverTaro',
position: 5ff163eb514e011e79ccc284,
__v: 0
},
__v: 0
}
//console.log(data.driver.name);
driverTaro
ご覧の様に、driverモデルが紐づいて取得できませんでした。
結果として問題があった部分は、
.populate("Driver")
populateメソッドの引数が原因でした。
populateメソッドには、**"モデル名"を指定するものだと思い込んでいました。
しかし、実際は引数に指定するのは、"外部キーに指定したkey"でした。
よって、今回であれば
.populate("driver")
のように、キー名を引数に渡すことにより、求める結果か取得できました。
データーの保存方法に問題があるとばかり思い込んで、そちらを中心に調べたので、時間を要してしまいました。
結果として、公式のサンプルコードを見れば、すぐに解決する問題でした。
ハマった時は、発想を切り替えて、エラーの原因を調査することが大切ですね。
参考:
[mongoose official]
(https://mongoosejs.com/docs/populate.html#saving-refs)