简体   繁体   中英

Indexing Array Items In Mongoose

I have a schema that looks something like ...

const itemSchema = new Schema({
    sizes: [{
        type: String,
        enum: [/* some fixed sizes */],
    }],
    // other properties ...
});

I perform queries of the form Items.find({ sizes: { $elemMatch: 'someSize' } });
So I want to add index to those sizes inside of an element so the query is performed quickly.

Should it be something like:

const itemSchema = new Schema({
    sizes: [{
        type: String,
        enum: [/* some fixed sizes */],
        index: true,
    }],
    // other properties ...
});

or

const itemSchema = new Schema({
    sizes: {
        type: [{
            type: String,
            enum: [/* some fixed sizes */],
        }],
        index: true,
    },
    // other properties ...
});

or maybe a third option ?

I discovered that what I wanted is called Multikey Indexing and found its docs on MongoDB .

According to that, indexing a field whose type is an array will create an index for each field of the array all pointing to the same document, which is exactly what I wanted to optimize my queries.

So the right answer would be

const itemSchema = new Schema({
    sizes: {
        type: [{
            type: String,
            enum: [/* some fixed sizes */],
        }],
        index: true,
    },
    // other properties ...
});

but on experimenting and checking collection indexes (with compass), I found that this

const itemSchema = new Schema({
    sizes: [{
        type: String,
        enum: [/* some fixed sizes */],
        index: true,
    }],
    // other properties ...
});

will also work in the same manner and will create an index on sizes field which will be a multikey index.

So pretty much the 2 forms are acceptable, and are working as expected; I prefer the one that explicitly indexes the sizes field though.

You can define indexes as part of the type declaration like this:

const itemSchema = new Schema({
    sizes: [{
        type: String,
        enum: ['foo', 'bar'],
        index: true,
    }],
    // other properties ...
});

You could also define them as @Eduardo mention after the fact via something like this:

itemSchema.index({ _id: 1 }, { sparse: true });

All is in the documentation .

What i do for indexing is: Below the schema i'll write itemSchema.index({'sizes':1}); You can check here in mongoose documentation for more info https://mongoosejs.com/docs/guide.html#indexes

Expanding @Amr Saber & @Akrion 's answer,
If anyone want also define default or required values,

const itemSchema = new Schema({
    sizes: [{ 
      type: [{
         type: String,
         enum: [/* some fixed sizes */],
         index: true,
      }],
      required: true, 
      default: [] 
    }],
    // other properties ...
});

can be used. It seems to work fine for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM