MongoDB - is there a better way to store a list of ObjectIDs?

743 Views Asked by At

Say I have a User schema/model and the user has a list of friends. Mongoose wants you to store your list of friends (foreign key / ObjectID type) as an array, right? Which means if I want to find my friend by ID, Mongoose will search the array until it finds the first instance of a friend with the ID I want. That seems really time inefficient no? Is there a better way?

const FriendSchema = new Schema({
  username: { type: String, required: true, unique: true },
});

const UserSchema = new Schema({
  username: { type: String, required: true, unique: true },
  friends: [FriendSchema],
});
2

There are 2 best solutions below

1
Matt Wang On

Use ref to refer to the documents in another schema and call populate to get the referred doc.

// friend.model.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const FriendSchema = new Schema({
  username: { type: String, required: true, unique: true },
});
module.exports = mongoose.model('Friend', FriendSchema);
// user.model.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const UserSchema = new Schema({
  username: { type: String, required: true, unique: true },
  friends: [{ type: Schema.Types.ObjectId, ref: 'Friend' }],
});
module.exports = mongoose.model('User', UserSchema);
const User = require('user.model.js');

User.find(...)
  .populate('friends')
  .exec()
0
Justin Jaeger On

Part of what I was looking for is this:

Indexes are what allows you to "iterate" through an array or a field in a collection without having to look at every single one. So to make sure you don't waste time iterating, you can create an "index" on any field and it makes it searchable in a binary-tree structure. https://docs.mongodb.com/manual/indexes/

Arrays already are made to have the field be a "key" so you wouldn't need to worry about the time complexity of searching an array by the field name of one of its elements. https://docs.mongodb.com/manual/core/index-multikey/