Search code examples
node.jsmongodbmongoosemongoose-schemamongoose-populate

using custom _id in mongodb, and linking to another object


I'm trying to use custom _id for mongodb objects.

I've two objects: User & Group

User:

const mongoose = require('mongoose');
const { Schema } = mongoose;

const ObjectId = Schema.Types.ObjectId;

const userSchema = new Schema(
    {
        //Username
        _id: {
            type: String,
            unique: true
        },

        name: {
            type: String,
            required: 'Name is required.'
        },

        //Groups [ group-unique-url ]
        Groups: {
            type: [ObjectId],
            default: []
        }
    },
    { _id: false }
);

mongoose.model('users', userSchema);

Group:

const mongoose = require('mongoose');
const { Schema } = mongoose;

const groupSchema = new Schema(
    {
        //unique URL
        _id: {
            type: String,
            unique: true
        },

        //Name of the Group
        name: {
            type: String,
            unique: true,
            required: true
        }
    },
    { _id: false }
);

mongoose.model('groups', groupSchema);

Saving user:

const user = new User({
    name: 'Surya Chandra',
    _id: 'surya'
});
user.save();

Saving group:

const group = new Group({
    name: 'StackOverflow',
    _id: 'stack.com' //unique
});
group.save();

Till here everything works fine. Now I've to link the group to the user.

userId => 'surya' & groupId => 'stack.com'

const user = await User.findById(userId); //'surya'

if (user.Groups.indexOf(groupId) >= 0) {
} else {
    user.Groups.push(groupId); //user.G.push(mongoose.Types.ObjectId(_g));
    user.save();
}

user.Groups.push(groupId)

CastError: Cast to ObjectId failed for value "stack.com" at path "Groups"

user.Groups.push(mongoose.Types.ObjectId(_g));

Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters

I'm not sure how to add the group to User Groups. How do I query for all the users in a particular group? Also, does this support populating the Group Names from the User Groups field?

Thanks.


Solution

  • In your userSchema, you should do like this instead

    const userSchema = new Schema(
    {
        //Username
        _id: {
            type: String,
            unique: true
        },
    
        name: {
            type: String,
            required: 'Name is required.'
        },
    
        groups: [{ type: Schema.Types.ObjectId, ref: 'groups'}]
    },
    );
    

    the ref: 'groups' must match the model name which you defined in your group model

    mongoose.model('groups', groupSchema);
    

    The to find the group later, you can use populate('groups'). Read mongoose docs for more detail I also don't understand why you want to override _id of mongoose. I don't think it will work. If you want to make a field unique, you can try other name.