Search code examples
node.jsmongoosepopulation

Mongoose populate Schema returns undefined


I have a little problem with nesting some sub documents with mongoose. I read a lot about this and tried nearly everything.

I really don't know what is wrong. I know there are really much questions about this in the web.A lot of them are similar, but nothing solved my problem.

The problem is, that my populated document always is empty.

  • I checked my Schemas
  • I deleted the whole Database
  • After that i rewrote the whole schemas and codes again.

Nothing helped. I think it is a really small problem, but i do not get it.

Here are my Schemas:

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

Output:

[{
probe: [],
    _id: 5db94f22d8fb641c18fc05b9,
    name: 'test',
    ip: '1.11.1.1',
    port: '111',
    secret:
     '$2b$10$2umat9QqHSFF9/zVih9LU.UKX4sPh/Lmq5XjSai0/pt42QfLXQb6u',
    __v: 0 
}]

What i excpect:


    _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 documents


{
   "_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
}


Solution

  • I strongly believe the problem arises because of the circular refs (device has ref to probe, probe has ref to device)

    In device model I would remove the ref to the device.

    probe.js ( I removed the ref to the device, and not included other fields for simplicity)

    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 ( I didn't included other fields for simplicity)

    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;
    

    With these changes, now you can get the devices with probes like this:

    router.get("/device", async (req, res) => {
      const devices = await Device.find({}).populate("probe");
    
      res.send(devices);
    });
    
    

    This will give you a resultset like this:

    [
        {
            "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
        }
    ]