2017-12-21 5 views
1

Ich programmiere eine App mit Node.js und MongooseJS als meine Middleware für die Verarbeitung von Datenbankaufrufen.MongooseJS gibt leeres Array nach der Population zurück

Mein Problem ist, dass ich einige verschachtelte Schemas habe und einer von ihnen in einer falschen Weise bevölkert ist. Wenn ich jeden Schritt der Population aufspüre - alle Daten sind in Ordnung, mit Ausnahme des Arrays devices, das leer ist. Ich überprüfte die Datenbank doppelt und es gibt Daten in diesem Array, also sollte es in Ordnung sein.

Ich habe Room Schema. Jedes Objekt von Room hat ein Feld namens DeviceGroups. Dieses Feld enthält einige Informationen und eine davon ist ein Array namens Devices, in dem Geräte gespeichert sind, die dem übergeordneten Raum zugewiesen sind.

Wie Sie im Code sehen können, finde ich einen Raum basierend auf seiner ID, die in der Anfrage an den Server kommt. Alles ist gut gefüllt und die Daten stimmen mit den Daten in der Datenbank überein. Problem ist, dass das Array devices leer ist.

Ist das eine Art von Eigenart von MongooseJS, oder mache ich hier etwas falsch, dass devices Array leer zurückgegeben wird? Ich habe die Datenbank selbst eingecheckt und es sind einige Daten darin, also sind die Daten in Ordnung, der Fehler ist irgendwo im eingefügten Code.

Der Code:

Schemen:

const roomSchema = Schema({ 
    name: { 
     type: String, 
     required: [true, 'Room name not provided'] 
    }, 
    deviceGroups: [{ 
     type: Schema.Types.ObjectId, 
     ref: 'DeviceGroup' 
    }] 
}, { collection: 'rooms' }); 

const deviceGroupSchema = Schema({ 
    parentRoomId: { 
     type: Schema.Types.ObjectId, 
     ref: 'Room' 
    }, 
    groupType: { 
     type: String, 
     enum: ['LIGHTS', 'BLINDS', 'ALARM_SENSORS', 'WEATHER_SENSORS'] 
    }, 
    devices: [ 
     { 
      type: Schema.Types.ObjectId, 
      ref: 'LightBulb' 
     }, 
     { 
      type: Schema.Types.ObjectId, 
      ref: 'Blind' 
     } 
    ] 
}, { collection: 'deviceGroups' }); 

const lightBulbSchema = Schema({ 
    name: String, 
    isPoweredOn: Boolean, 
    currentColor: Number 
}, { collection: 'lightBulbs' }); 

const blindSchema = Schema({ 
    name: String, 
    goingUp: Boolean, 
    goingDown: Boolean 
}, { collection: 'blinds' }); 

Datenbank Aufruf:

Room 
    .findOne({ _id: req.params.roomId }) 
    .populate({ 
     path: 'deviceGroups', 
     populate: { 
      path: 'devices' 
     } 
    }) 
    .lean() 
    .exec(function(err, room) { 
     if (err) { 
      res.send(err); 
     } else { 
      room.deviceGroups.map(function(currentDeviceGroup, index) { 
       if (currentDeviceGroup.groupType === "BLINDS") { 
        var blinds = room.deviceGroups[index].devices.map(function(currentBlind) { 
        return { 
         _id: currentBlind._id, 
         name: currentBlind.name, 
         goingUp: currentBlind.goingUp, 
         goingDown: currentBlind.goingDown 
        } 
       }); 
       res.send(blinds); 
      } 
     }); 
    } 
}) 
+0

Ich glaube nicht, dass die Art, wie Sie "Geräte" definiert haben, richtig ist. Eine Möglichkeit, mehrere Schemarefs in einem Array zu haben, ist die Verwendung von [discriminator] (http://mongoosejs.com/docs/api.html#model_Model.discriminator) siehe [Antwort] (https://stackoverflow.com/a/35470271/3284355) – Molda

+0

@Molda könntest du mir ein einfaches Beispiel geben, wie das geht? Natürlich ist 'discriminator' genau das, was ich gesucht habe, aber der andere Post, den Sie verlinkt haben, ist ein bisschen kompliziert wegen der ganzen Middleware, die er benutzt, und es ist nicht sehr klar für mich. Könnten Sie mir ein Beispiel geben, wie ich das in meinem Fall anwenden könnte? Danke –

Antwort

1

Dies ist ein Beispiel für die Verwendung der Methode discriminator, um mehrere Schemas in einem einzigen Array verwenden zu können.

const roomSchema = Schema({ 
    name: { 
     type: String, 
     required: [true, 'Room name not provided'] 
    }, 
    deviceGroups: [{ type: Schema.Types.ObjectId, ref: 'DeviceGroup' }] 
}); 

const deviceGroupSchema = Schema({ 
    parentRoom: { type: Schema.Types.ObjectId, ref: 'Room' }, 
    groupType: { 
     type: String, 
     enum: ['LIGHTS', 'BLINDS', 'ALARM_SENSORS', 'WEATHER_SENSORS'] 
    }, 
    devices: [{ type: Schema.Types.ObjectId, ref: 'Device' }] 
}); 

// base schema for all devices 
function DeviceSchema() { 
    Schema.apply(this, arguments); 

    // add common props for all devices 
    this.add({ 
    name: String 
    }); 
} 

util.inherits(DeviceSchema, Schema); 

var deviceSchema = new DeviceSchema(); 

var lightBulbSchema = new DeviceSchema({ 
    // add props specific to lightBulbs 
    isPoweredOn: Boolean, 
    currentColor: Number 
}); 

var blindSchema = new DeviceSchema({ 
    // add props specific to blinds 
    goingUp: Boolean, 
    goingDown: Boolean 
}); 

var Room = mongoose.model("Room", roomSchema); 
var DeviceGroup = mongoose.model("DeviceGroup", deviceGroupSchema); 

var Device = mongoose.model("Device", deviceSchema); 

var LightBulb = Device.discriminator("LightBulb", lightBulbSchema); 
var Blind = Device.discriminator("Blind", blindSchema); 

// this should return all devices 
Device.find() 
// this should return all devices that are LightBulbs 
LightBulb.find() 
// this should return all devices that are Blinds 
Blind.find() 

In der Kollektion finden Sie __t Eigenschaft auf jedem Gerät mit Werten nach dem Schema verwendet (LightBulb oder blind)

Ich habe sehen Sie den Code nicht versucht, und ich habe Mungo nicht verwendet in eine Weile, aber ich hoffe, dass es funktionieren wird :)

aktualisieren - geprüfte Funktion Beispiel

var mongoose = require('mongoose'); 
var Schema = mongoose.Schema; 
var util = require('util'); 

const roomSchema = Schema({ 
    name: { 
     type: String, 
     required: [true, 'Room name not provided'] 
    }, 
    deviceGroups: [{ type: Schema.Types.ObjectId, ref: 'DeviceGroup' }] 
}); 

const deviceGroupSchema = Schema({ 
    parentRoomId: { type: Schema.Types.ObjectId, ref: 'Room' }, 
    groupType: { 
     type: String, 
     enum: ['LIGHTS', 'BLINDS', 'ALARM_SENSORS', 'WEATHER_SENSORS'] 
    }, 
    devices: [{ type: Schema.Types.ObjectId, ref: 'Device' }] 
}); 

// base schema for all devices 
function DeviceSchema() { 
    Schema.apply(this, arguments); 

    // add common props for all devices 
    this.add({ 
    name: String 
    }); 
} 

util.inherits(DeviceSchema, Schema); 

var deviceSchema = new DeviceSchema(); 

var lightBulbSchema = new DeviceSchema({ 
    // add props specific to lightBulbs 
    isPoweredOn: Boolean, 
    currentColor: Number 
}); 

var blindSchema = new DeviceSchema(); 
blindSchema.add({ 
    // add props specific to blinds 
    goingUp: Boolean, 
    goingDown: Boolean 
}); 


var Room = mongoose.model("Room", roomSchema); 
var DeviceGroup = mongoose.model("DeviceGroup", deviceGroupSchema); 

var Device = mongoose.model("Device", deviceSchema); 

var LightBulb = Device.discriminator("LightBulb", lightBulbSchema); 
var Blind = Device.discriminator("Blind", blindSchema); 


var conn = mongoose.connect('mongodb://127.0.0.1/test', { useMongoClient: true }); 

conn.then(function(db){ 

    var room = new Room({ 
     name: 'Kitchen' 
    }); 

    var devgroup = new DeviceGroup({ 
     parentRoom: room._id, 
     groupType: 'LIGHTS' 
    }); 

    var blind = new Blind({ 
     name: 'blind1', 
     goingUp: false, 
     goingDown: true 
    }); 
    blind.save(); 

    var light = new LightBulb({ 
     name: 'light1', 
     isPoweredOn: false, 
     currentColor: true 
    }); 
    light.save(); 

    devgroup.devices.push(blind._id); 
    devgroup.devices.push(light._id); 
    devgroup.save(); 

    room.deviceGroups.push(devgroup._id); 
    room.save(function(err){ 
     console.log(err); 
    }); 

    // Room 
    // .find() 
    // .populate({ 
    //  path: 'deviceGroups', 
    //  populate: { 
    //   path: 'devices' 
    //  } 
    // }) 
    // .then(function(result){ 
    //  console.log(JSON.stringify(result, null, 4)); 
    // }); 

}).catch(function(err){ 

}); 
+0

kommt, schlagen Sie vor, die Funktion 'util.inherits (DeviceSchema , Schema); '. Meine Frage ist: Was ist 'util'? Ich sehe es nirgends erklärt. ist es wie ein anderes Paket von NPM oder vielleicht etwas von Mungo selbst? –

+0

Ich habe Ihre Lösung verwendet und bekomme immer noch ein leeres Array. Ich überprüfte die Datenbank und Daten werden dort gespeichert. Diese ist die Ausgabe: [{_id: undefined, Name: undefined, goingUp: undefined, goingDown: undefined}] –

+0

'util' ist eingebautes Modul, benötigen sie nur' var util = require (‘ util ') ' – Molda

0

Können Sie alles in Ihnen else-Anweisung löschen und

console.log(room) 

Ihre Mongo Speicher überprüfen zu machen sicher, dass Sie Daten in Ihrer Sammlung haben.

+0

Ich habe das getan, bevor Sie die Frage stellen.Wie ich in der Post selbst schrieb - ich überprüfte die Datenbank und alles hat richtige ID-Referenzen gespeichert, ich habe 'room' protokolliert und alles ist korrekt ausgefüllt außer dem' devices'-Array, das leer –

Verwandte Themen