猫鼬填充架构 returns 未定义
Mongoose populate Schema returns undefined
我在用 mongoose 嵌套一些子文档时遇到了一点问题。我读了很多关于这方面的文章并尝试了几乎所有的方法。
真不知道怎么回事。
我知道 web.A 中确实有很多关于此的问题,其中很多都很相似,但没有解决我的问题。
问题是,我填充的文档总是空的。
- 我检查了我的模式
- 我删除了整个数据库
- 之后我又重写了整个模式和代码。
没有任何帮助。
我认为这是一个非常小的问题,但我不明白。
这是我的模式:
probe.js
const ProbeShema = new mongoose.Schema({
device: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Device'
},
value: {
type: String,
required: true,
enum: ['Energy', 'Consumption', 'Voltage', 'Current', 'Frequency', 'Time', 'Date']
},
unit: {
type: String,
required: true,
enum: ['kWh', 'kW', 'V', 'A', 'Hz', 'time', 'date']
},
oid: {
type: String,
required: true
},
measurement: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Measurement'
}
});
const Probe = mongoose.model('Probe', ProbeShema,'probe');
module.exports = Probe;
devices.js
var mongoose = require('mongoose');
const DeviceShema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
ip: {
type: String,
required: true,
unique: true,
trim: true
},
port: {
type: String,
required: true,
trim: true
},
secret: {
type: String,
required: true,
trim: true
},
probe: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Probe'
}]
});
const Device = mongoose.model('Device', DeviceShema,'device');
module.exports = Device;
var express = require('express');
var router = express.Router();
var Device = require('../../models/devices')
Device.find()
.populate( 'probe')
.exec()
.then(devices => {
console.log(devices)
res.render('./snmp/snmp', { "title": "SNMP-Devices", "devices": devices });
})
.catch(err => {
console.log(err)
});
输出:
[{
probe: [],
_id: 5db94f22d8fb641c18fc05b9,
name: 'test',
ip: '1.11.1.1',
port: '111',
secret:
'bumat9QqHSFF9/zVih9LU.UKX4sPh/Lmq5XjSai0/pt42QfLXQb6u',
__v: 0
}]
我期待的是:
_id: 5db94f22d8fb641c18fc05b9,
name: 'test',
ip: '1.11.1.1',
port: '111',
secret:
'bumat9QqHSFF9/zVih9LU.UKX4sPh/Lmq5XjSai0/pt42QfLXQb6u',
probe: [
{
device: '5db94f22d8fb641c18fc05b9',
value: 'Energy',
unit: 'kWh',
oid:'1.1.1.1.11',
measurement: 11
},{
device: '5db94f22d8fb641c18fc05b9',
value: 'Consumption',
unit: 'kW',
oid:'1.1.1.1.12',
measurement: 500
}
]
MongoDB 文档
{
"_id":"5db95821d3a65d20200cda64",
"device":"5db9581fd3a65d20200cda63",
"oid":"asd",
"value":"Energy",
"unit":"kWh","__v":0
}
{
"_id":"5db9581fd3a65d20200cda63",
"probe":[],
"name":"asd",
"ip":"1.1.1.1",
"port":"1",
"secret":"b$mr4x4ls0J2CqdNxnk/ih2.FAHpj1fsXT2NsgrzDXF9y4LCnZBNfXa",
"__v":0
}
我坚信问题的出现是因为循环引用(设备有引用到探测,探测器有引用到设备)
在设备模型中,我会删除对设备的引用。
probe.js(我删除了设备的引用,为了简单起见不包括其他字段)
const mongoose = require("mongoose");
const ProbeShema = new mongoose.Schema(
{
value: {
type: String,
required: true,
enum: [
"Energy",
"Consumption",
"Voltage",
"Current",
"Frequency",
"Time",
"Date"
]
}
}
);
const Probe = mongoose.model("Probe", ProbeShema, "probe");
module.exports = Probe;
device.js(为简单起见,我没有包含其他字段)
var mongoose = require("mongoose");
const DeviceShema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
probe: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Probe"
}
]
});
const Device = mongoose.model("Device", DeviceShema, "device");
module.exports = Device;
通过这些更改,现在您可以获得带有如下探头的设备:
router.get("/device", async (req, res) => {
const devices = await Device.find({}).populate("probe");
res.send(devices);
});
这将为您提供如下结果集:
[
{
"probe": [
{
"_id": "5db96a460ef8cc1c9c45e7f4",
"value": "Energy",
"__v": 0
},
{
"_id": "5db96aa30ef8cc1c9c45e7f5",
"value": "Consumption",
"__v": 0
}
],
"_id": "5db96f13d8faa752cc9e2cf9",
"name": "Device 1",
"__v": 0
},
{
"probe": [
{
"_id": "5db96a460ef8cc1c9c45e7f4",
"value": "Energy",
"__v": 0
},
{
"_id": "5db96aa30ef8cc1c9c45e7f5",
"value": "Consumption",
"__v": 0
},
{
"_id": "5db96f96b59c3139bce431bd",
"value": "Voltage",
"__v": 0
}
],
"_id": "5db96fb1b59c3139bce431be",
"name": "Device 2",
"__v": 0
}
]
你可以试试这个 -
Device.aggregate([
// Unwind the source
{ "$unwind": "$devices" },
// Do the lookup matching
{ "$lookup": {
"from": "probe",
"localField": "probe",
"foreignField": "_id",
"as": "proeObjects"
}},
// Unwind the result arrays ( likely one or none )
{ "$unwind": "$proeObjects" },
// Group back to arrays
{ "$group": {
"_id": "$_id",
"devices": { "$push": "$devices" },
"proeObjects": { "$push": "$proeObjects" }
}}
], (err, result) => { console.log(err || )})
感谢您的帮助。
我真的误会了什么。它不时变得更清晰。
我认为代码本身并没有错。
问题是,填充不是按我预期的那样工作。
我必须对此进行一些测试和尝试以了解更多信息。
我似乎还不清楚。
我来自 MySQL,处理方式完全不同。
如何保存不同模型之间的约束等问题让我很头疼。我以为populate只是比较id,然后嵌套,其实不是这样的。 (!?)
它现在似乎可以工作了,因为我在数组 probs 中添加了 id。
我有很多问题,但我必须自己回答。
当你认为你离目标如此之近并看到隧道尽头的光时真的很难,但实际上你刚刚到达隧道^^
感谢大家,抱歉让您久等了,而且我的英语不好。
此致
我在用 mongoose 嵌套一些子文档时遇到了一点问题。我读了很多关于这方面的文章并尝试了几乎所有的方法。
真不知道怎么回事。 我知道 web.A 中确实有很多关于此的问题,其中很多都很相似,但没有解决我的问题。
问题是,我填充的文档总是空的。
- 我检查了我的模式
- 我删除了整个数据库
- 之后我又重写了整个模式和代码。
没有任何帮助。 我认为这是一个非常小的问题,但我不明白。
这是我的模式:
probe.js
const ProbeShema = new mongoose.Schema({
device: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Device'
},
value: {
type: String,
required: true,
enum: ['Energy', 'Consumption', 'Voltage', 'Current', 'Frequency', 'Time', 'Date']
},
unit: {
type: String,
required: true,
enum: ['kWh', 'kW', 'V', 'A', 'Hz', 'time', 'date']
},
oid: {
type: String,
required: true
},
measurement: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Measurement'
}
});
const Probe = mongoose.model('Probe', ProbeShema,'probe');
module.exports = Probe;
devices.js
var mongoose = require('mongoose');
const DeviceShema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
ip: {
type: String,
required: true,
unique: true,
trim: true
},
port: {
type: String,
required: true,
trim: true
},
secret: {
type: String,
required: true,
trim: true
},
probe: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Probe'
}]
});
const Device = mongoose.model('Device', DeviceShema,'device');
module.exports = Device;
var express = require('express');
var router = express.Router();
var Device = require('../../models/devices')
Device.find()
.populate( 'probe')
.exec()
.then(devices => {
console.log(devices)
res.render('./snmp/snmp', { "title": "SNMP-Devices", "devices": devices });
})
.catch(err => {
console.log(err)
});
输出:
[{
probe: [],
_id: 5db94f22d8fb641c18fc05b9,
name: 'test',
ip: '1.11.1.1',
port: '111',
secret:
'bumat9QqHSFF9/zVih9LU.UKX4sPh/Lmq5XjSai0/pt42QfLXQb6u',
__v: 0
}]
我期待的是:
_id: 5db94f22d8fb641c18fc05b9,
name: 'test',
ip: '1.11.1.1',
port: '111',
secret:
'bumat9QqHSFF9/zVih9LU.UKX4sPh/Lmq5XjSai0/pt42QfLXQb6u',
probe: [
{
device: '5db94f22d8fb641c18fc05b9',
value: 'Energy',
unit: 'kWh',
oid:'1.1.1.1.11',
measurement: 11
},{
device: '5db94f22d8fb641c18fc05b9',
value: 'Consumption',
unit: 'kW',
oid:'1.1.1.1.12',
measurement: 500
}
]
MongoDB 文档
{
"_id":"5db95821d3a65d20200cda64",
"device":"5db9581fd3a65d20200cda63",
"oid":"asd",
"value":"Energy",
"unit":"kWh","__v":0
}
{
"_id":"5db9581fd3a65d20200cda63",
"probe":[],
"name":"asd",
"ip":"1.1.1.1",
"port":"1",
"secret":"b$mr4x4ls0J2CqdNxnk/ih2.FAHpj1fsXT2NsgrzDXF9y4LCnZBNfXa",
"__v":0
}
我坚信问题的出现是因为循环引用(设备有引用到探测,探测器有引用到设备)
在设备模型中,我会删除对设备的引用。
probe.js(我删除了设备的引用,为了简单起见不包括其他字段)
const mongoose = require("mongoose");
const ProbeShema = new mongoose.Schema(
{
value: {
type: String,
required: true,
enum: [
"Energy",
"Consumption",
"Voltage",
"Current",
"Frequency",
"Time",
"Date"
]
}
}
);
const Probe = mongoose.model("Probe", ProbeShema, "probe");
module.exports = Probe;
device.js(为简单起见,我没有包含其他字段)
var mongoose = require("mongoose");
const DeviceShema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
probe: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Probe"
}
]
});
const Device = mongoose.model("Device", DeviceShema, "device");
module.exports = Device;
通过这些更改,现在您可以获得带有如下探头的设备:
router.get("/device", async (req, res) => {
const devices = await Device.find({}).populate("probe");
res.send(devices);
});
这将为您提供如下结果集:
[
{
"probe": [
{
"_id": "5db96a460ef8cc1c9c45e7f4",
"value": "Energy",
"__v": 0
},
{
"_id": "5db96aa30ef8cc1c9c45e7f5",
"value": "Consumption",
"__v": 0
}
],
"_id": "5db96f13d8faa752cc9e2cf9",
"name": "Device 1",
"__v": 0
},
{
"probe": [
{
"_id": "5db96a460ef8cc1c9c45e7f4",
"value": "Energy",
"__v": 0
},
{
"_id": "5db96aa30ef8cc1c9c45e7f5",
"value": "Consumption",
"__v": 0
},
{
"_id": "5db96f96b59c3139bce431bd",
"value": "Voltage",
"__v": 0
}
],
"_id": "5db96fb1b59c3139bce431be",
"name": "Device 2",
"__v": 0
}
]
你可以试试这个 -
Device.aggregate([
// Unwind the source
{ "$unwind": "$devices" },
// Do the lookup matching
{ "$lookup": {
"from": "probe",
"localField": "probe",
"foreignField": "_id",
"as": "proeObjects"
}},
// Unwind the result arrays ( likely one or none )
{ "$unwind": "$proeObjects" },
// Group back to arrays
{ "$group": {
"_id": "$_id",
"devices": { "$push": "$devices" },
"proeObjects": { "$push": "$proeObjects" }
}}
], (err, result) => { console.log(err || )})
感谢您的帮助。 我真的误会了什么。它不时变得更清晰。 我认为代码本身并没有错。
问题是,填充不是按我预期的那样工作。 我必须对此进行一些测试和尝试以了解更多信息。 我似乎还不清楚。 我来自 MySQL,处理方式完全不同。
如何保存不同模型之间的约束等问题让我很头疼。我以为populate只是比较id,然后嵌套,其实不是这样的。 (!?)
它现在似乎可以工作了,因为我在数组 probs 中添加了 id。
我有很多问题,但我必须自己回答。 当你认为你离目标如此之近并看到隧道尽头的光时真的很难,但实际上你刚刚到达隧道^^
感谢大家,抱歉让您久等了,而且我的英语不好。
此致