Jesper Jesper -4 years ago 126
Node.js Question

Connect mongoose-array-values to a unique ID

This may seem like a vague question, but I'm going to try to explain the best I can. As a side note, I'm quite new to using mongoose :)

I have a mongoose-schema storing different values for each user, like so...

let userSchema = mongoose.Schema({
user: { type: String, required: true, unique: true },
pass: { type: String, required: true },
files: [{ type: String, required: false }],
});


The "files"-key contains an array of values, lets say for example:

userSchema.files = [value1, value2, value3]


And I want each value to be connected to some kind of ID, so that when I call the specified ID, I get the specified value. Just for demonstrating purposes, it could look something like this:

userSchema.files = [{value:value1, id: id1},
{value:value2, id: id2},
{value:value3, id: id3}]


Then I want to find the specified id, and return it's "value"-key in a request:

router.route("/home/:id")
.get(restrict, function(req, res) {

User.findOne({ user: req.session.Auth.username }, function(error, data) {
data.files.forEach(function(file) {
if (file.id === req.params.id) {
response.render("../home", file.value)
}
}
});
});


How can I do this? Tried pushing an object to files, but that didn't work as expected. Read something about ObjectId, but couldn't quite understand it. Any tips?

Answer Source

I think you simply need to create a separate model for File and connect it to your User model using the 'ref' keyword :

let fileSchema = mongoose.Schema({
    _id     : Number,
    value    : String
});

let userSchema = mongoose.Schema({
    user: { type: String, required: true, unique: true },
    pass: { type: String, required: true },
    files: [{ type: Number, ref: 'File' }]
});

let User  = mongoose.model('User', userSchema);
let File  = mongoose.model('File', fileSchema);

let f1 = new File({ _id: 1, value: 'File 1'});
let f2 = new File({ _id: 2, value: 'File 2'});
let f3 = new File({ _id: 3, value: 'File 3'});

let user1 = new User({user:'chuck', pass:'norris'});
user1.files.push(f1);
user1.files.push(f2);
user1.files.push(f3);

user1.save(function(err){  });

Now to get the data back:

User
.findOne({ user: 'chuck' })
.populate('files') // only works if we pushed refs to children
.exec(function (err, user) {
  if (err) return handleError(err);
  console.log(user);
  //you can now loop through user.files and compare _id
  user.files.forEach(function(file) {
      if (file._id === req.params.id) {
         response.render("../home", file.value)
      }
   }
});

You can read about mongoose reference population here: http://mongoosejs.com/docs/populate.html

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download