【问题标题】:Mongoose populate Schema returns undefinedMongoose 填充模式返回未定义
【发布时间】:2019-10-30 09:52:08
【问题描述】:

我在用 mongoose 嵌套一些子文档时遇到了一点问题。我阅读了很多关于此的内容并尝试了几乎所有方法。

我真的不知道出了什么问题。 我知道网络上有很多关于这个的问题。很多都是相似的,但没有解决我的问题。

问题是,我填充的文档总是空的。

  • 我检查了我的架构
  • 我删除了整个数据库
  • 之后我再次重写了整个架构和代码。

没有任何帮助。 我认为这是一个非常小的问题,但我不明白。

这是我的架构:

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:
     '$2b$10$2umat9QqHSFF9/zVih9LU.UKX4sPh/Lmq5XjSai0/pt42QfLXQb6u',
    __v: 0 
}]

我的期望:


    _id: 5db94f22d8fb641c18fc05b9,
    name: 'test',
    ip: '1.11.1.1',
    port: '111',
    secret:
     '$2b$10$2umat9QqHSFF9/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":"$2b$10$mr4x4ls0J2CqdNxnk/ih2.FAHpj1fsXT2NsgrzDXF9y4LCnZBNfXa",
   "__v":0
}

【问题讨论】:

  • 在你的数据库中,探针数组是空的?
  • 对不起,可能写得不清楚。最后一部分显示了这两个文件。第一个是探头,第二个是设备。所以应该有一个探针
  • 但设备中的探测字段不包含任何内容
  • 哦...:/你的权利。该实体不应该在那里列出,对吧?!人口通过 id 参考探测文档自动执行此操作?!换句话说:在数据库中的文档“设备”中的探测器不是列表。
  • 是的。探测字段应该是一个对象 id 数组,然后人口将起作用

标签: node.js mongoose population


【解决方案1】:

我坚信问题的出现是因为循环引用(设备有 ref 到探针,探针有 ref 到设备)

在设备模型中,我会删除设备的引用。

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
    }
]

【讨论】:

    【解决方案2】:

    你可以试试这个——

    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 || )})
    

    【讨论】:

      【解决方案3】:

      感谢您的帮助。 我真的误会了什么。它不时变得更清晰。 我认为代码本身并没有错。

      问题是,填充 not 按我的预期工作。 我必须对此进行一些测试和玩,以了解更多信息。 对我来说似乎仍然不清楚。 我来自 MySQL,处理方式完全不同。

      关于如何保存不同模型之间的约束等等,我有很多麻烦。我认为填充只是比较 id,然后嵌套它,但事实并非如此。 (!?)

      现在似乎可以工作了,因为我在数组 probs 中添加了 id。

      我有很多问题,但我必须自己回答。 当你认为自己如此接近目标并看到隧道尽头的光时,真的很难,但实际上你刚刚到达隧道^^

      谢谢大家,很抱歉等待时间和我的英语不好。

      最好的问候

      【讨论】:

      • 如果任何答案对您有帮助,请标记为答案或点赞。
      猜你喜欢
      • 2019-09-17
      • 2014-11-02
      • 1970-01-01
      • 2017-01-28
      • 2020-08-24
      • 2020-07-11
      • 1970-01-01
      • 2016-12-04
      • 2019-06-17
      相关资源
      最近更新 更多