117

I'm trying to find documentation, to no avail, on how to create multi-field indexes in Mongoosejs. In particular I have two fields that need to be indexed and unique. What is an example mongoose schema that indexes two fields together?

Dan
  • 3,389
  • 5
  • 34
  • 44

5 Answers5

242

You call the index method on your Schema object to do that as shown here. For your case it would be something like:

mySchema.index({field1: 1, field2: 1}, {unique: true});
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • 4
    This is called the Compount Index in mongodb. So it creates indexes as field1 and field1 + field2. So it is first index according to field1 and then inside field1 with respect to field 2 – Ketan Ghumatkar Jul 24 '15 at 15:46
  • 1
    what is the meaning of the 1 after field1: and field2: ? – Damon Yuan Oct 26 '15 at 05:04
  • 11
    @DamonYuan They set the sort order of the fields in the index. `1` is ascending, `-1` would be descending. – JohnnyHK Oct 27 '15 at 00:05
  • @KetanGhumatkar How are you sure that it is field1 and field1 + field2, and not viceversa i.e. field2 and field2 + field1? – Praveen Oct 26 '16 at 12:47
  • 1
    @KetanGhumatkar It's based on the order the fields are listed in the object in the call to `index`. – JohnnyHK Oct 26 '16 at 13:01
  • 2
    `1` and `-1` specifies a ascending or a descending index key on the index field. I found docs [http://mongodb.github.io/node-mongodb-native/2.1/tutorials/create-indexes/](http://mongodb.github.io/node-mongodb-native/2.1/tutorials/create-indexes) – Thai Ha Feb 11 '19 at 03:36
  • 1
    i do not think the `unique` works with compound indexes. – OhadR Apr 27 '20 at 18:48
  • 1
    creating Index option using code works in case you have 'autoIndex' set to true, however this is not an good practice in production as it put significant load. https://mongoosejs.com/docs/guide.html#indexes – nitin1416 Feb 11 '21 at 12:21
12

Defining indexes at the schema level is necessary when creating compound indexes.

animalSchema.index({ name: 1, type: -1 });

Reference: http://mongoosejs.com/docs/guide.html#indexes

Hugo Dozois
  • 8,147
  • 12
  • 54
  • 58
Krumb
  • 161
  • 1
  • 6
  • 7
    What is the meaning of 1 and -1? I couldn't find this in the documentation that you referenced to. Thanks. – DFB May 21 '15 at 03:59
  • 3
    I found the answer on this page: http://docs.mongodb.org/manual/core/indexes-introduction/ Thanks! – DFB May 21 '15 at 04:05
1
import { Schema, Document, model } from 'mongoose';

import { IUser } from './User';
import { IMood } from './Mood';
import { ILocation } from './Location';

export interface IUserMoodLocation extends Document {
    userId?: IUser['_id'];
    moodId?: IMood['_id'];
    locationId?: ILocation['_id'];
}

const UserMoodLocationSchema: Schema = new Schema({
    userId: {
        type: Schema.Types.ObjectId,
        required: true,
        ref: 'User'
    },
    moodId: {
        type: Schema.Types.ObjectId,
        required: true,
        ref: 'Mood'
    },
    locationId: {
        type: Schema.Types.ObjectId,
        required: true,
        ref: 'Location'
    }
});

UserMoodLocationSchema.index(
    { userId: 1, moodId: 1, locationId: 1 },
    { unique: true }
);

export const UserMoodLocation = model<IUserMoodLocation>(
    'UserMoodLocation',
    UserMoodLocationSchema
);
Shady Smaoui
  • 867
  • 9
  • 11
-4
    Following command can be used to create compound index for nested json:
    db.ACCOUNT_collection.createIndex({"account.id":1,"account.customerId":1},{unique:1}) 
Mongo json structure is like :
{"_id":"648738"
 "account": { 
    "id": "123",
    "customerId": 7879,
    "name": "test"
   ..
   ..

  }
}

I have tested with sample data it is perfectly working as expected.

Rajeev Rathor
  • 1,830
  • 25
  • 20
-5

By the way, the accepted answer is wrong, as per https://stackoverflow.com/a/52553550/129300 you should wrap the field names in single quotes, ie:

mySchema.index({'field1': 1, 'field2': 1}, {unique: true});

Happy Day!

Fer Martin
  • 1,541
  • 1
  • 13
  • 13
  • 9
    Object keys in JS can be unquoted as long as they're syntactically-valid identifiers. `field1` and `field2` are valid identifiers. `field1.foo` isn't, for example. – Gus Apr 29 '20 at 10:50
  • The answer is working though, but the accepted answer isn't wrong either as far as the object keys are valid. – Radical Edward Jul 21 '22 at 13:52