11

i'm using mongoose with nodejs, and i need to create a dynamic schema model, this is my code:

schema.add({key : String});

key = "user_name", but in my db i found that the model take it as key

{ key : "Michele" } and not { user_name: "Michele"}

What can i do? thank you.

Ahmed Commando
  • 723
  • 2
  • 7
  • 23

5 Answers5

16

The same issue schema with variable key is talked in mongoose,

Nope not currently possible. Closest alternative is to use strict: false or the mixed schema type.

Update

After Mongoose 5.1.0, we can use the terms 'map', maps are how you create a nested document with arbitrary keys

const userSchema = new Schema({
  // `socialMediaHandles` is a map whose values are strings. A map's
  // keys are always strings. You specify the type of values using `of`.
  socialMediaHandles: {
    type: Map,
    of: String
  }
});

const User = mongoose.model('User', userSchema);
// Map { 'github' => 'vkarpov15', 'twitter' => '@code_barbarian' }
console.log(new User({
  socialMediaHandles: {
    github: 'vkarpov15',
    twitter: '@code_barbarian'
  }
}).socialMediaHandles);

zangw
  • 43,869
  • 19
  • 177
  • 214
  • thank you but can i at least do this key : {type : schematype } passing another schema as a type? – Ahmed Commando Mar 26 '16 at 15:31
  • @AhmedCommando, it seems another question here. However, you can try `var schematype='String';`, then use it in the schema `key : {type : schematype }` – zangw Mar 27 '16 at 00:22
  • 1
    This issue has been resolved inside the post above. Or you can check https://mongoosejs.com/docs/schematypes.html#maps – Wenlong Jiang May 25 '21 at 01:40
10

If I understand correctly, you want to add a new column to your schema whose key is generated dynamically. E.g. maybe a collection of posts per user, where the heading of post is the key. If a user creates a new post, it gets added to his collection with the key as his post's heading.

When you originally did

let schema = new Schema({ id: String, ... , key: String })

mongoose took key literally, just like it took id literally.

The reason why you cannot add keys dynamically to the root of the schema is because then mongoose can't guarantee any structure. You might as well do strict: false, as others have suggested, to make the entire schema free-form.

However, if you don't want to make the entire schema free-form, but only a certain portion of it, you can also modify your schema to use mixed

let schema = new Schema({ id: String, ... , posts: Schema.Types.Mixed })

Now you can save all your dynamically generated keys under posts which is free-form.

You can also do above with map:

let schema = new Schema({ id: String, ... , posts: {type: Map, of: String} })

This will allow you to create any key-value pair inside the posts structure.

Rash
  • 7,677
  • 1
  • 53
  • 74
2

simply use this in mongoose schema,

users: { type: Map, of: Object },

this will allow you to insert data in below format, and you can put additional data against each user id.

.
.
"users": {
    "63149e352b575f267b80565d": {},
    "63149e352b575f267b80565e": {}
},
.
.
Krishan Pal
  • 306
  • 1
  • 3
1
const options = {};
options[key] = String;

schema.add(options);
Prateek Gupta
  • 2,422
  • 2
  • 16
  • 30
samuel
  • 23
  • 1
  • 8
0

You can do like this:

posts: { type: Object }

And inside posts key, you can implement any key-value pair you would like to