Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map in Mongoose

I'm trying to create a schema in Mongoose that have a map (object, associative array, key-value pairs), but no success so far.
The documents of my schema must be something like this:

{
    "_id": ObjectId("..."),
    "groups"
    {
        "groupA":
        {
            "value1": "...",
            "value2": "..."
        },
        "groupB":
        {
            "value3": "...",
        },
        "groupC":
        {
            "value4": "...",
            "value5": "...",
        },
        ...
    }
}

groups is as object with a variable number of keys. I don't know those keys ahead of time as it'll be create by the user.
Every entry in groups is another object. As before, I don't know the key identifiers, but I know that the values are String (or Boolean, or Number, doesn't matter).
Of course, those keys are Strings.

Is it even possible (is there anyway to build such schema/model) in Mongoose?

like image 377
NemoStein Avatar asked Jan 28 '15 19:01

NemoStein


4 Answers

Best practice is to keep any dynamic data out of your field names. The typical approach for a use case like this is to make groups an array and move the name of the group into a name field of the contained objects. Then you can use the Mixed type to contain the user-defined set of values:

{
    "_id": ObjectId("..."),
    "groups":
    [
        {
            name: "groupA",
            values: {
                "value1": "...",
                "value2": "..."
            }
        },
        {
            name: "groupB",
            values: {
                "value3": "..."
            }
        },
        {
            name: "groupC",
            values: {
                "value4": "...",
                "value5": "..."
            }
        },
        ...
    ]
}

You'd define the schema as:

var schema = new Schema({
    groups: [{
        name: String,
        values: Schema.Types.Mixed
    }]
});
like image 76
JohnnyHK Avatar answered Oct 19 '22 23:10

JohnnyHK


Map is supported from version 5.1 - http://mongoosejs.com/docs/schematypes.html#maps

like image 45
o.z Avatar answered Oct 19 '22 22:10

o.z


Looks like somebody made a plugin, Hooray!

https://www.npmjs.com/package/mongoose-map

Once you install and configure according to the readme you can just do {groups:[MongooseMap]}...

like image 3
user3413723 Avatar answered Oct 19 '22 21:10

user3413723


Have you tried something like this:

var schema = new mongoose.Schema({
    groups: [mongoose.Schema.Types.Mixed]
});

Reference: Mongoose Schema Types

Edit, given my comments below, and riffing on the answer before mine, let's assume that all values are of type string (I had understood that they might be anything):

var schema = new mongoose.Schema({
    groups:[{
        name: String,
        values:[String]
    }]
});

Edit #2: Assuming that "value1" is a placeholder for some more meaningful name and assuming that the number of member names is finite, as long as they are not required, then you can put them all in your schema, so instead of the array version, you should be able to do this:

var schema = new mongoose.Schema({
    groups:[{
        name: String,
        value1: String,
        value2: String,
        value3: String,
        value4: String,
        value5: String
    }]
});
like image 1
Mark Lybrand Avatar answered Oct 19 '22 22:10

Mark Lybrand