Bill
Bill

Reputation: 5150

Mongoose: Add text index to nested schema

I want to be able to find a user based on their shared.username or shared.email everything before the @ or shared.fullName do I just change index: true to index: text for each of the fields I want to text search on??

const userSchema: Schema = new Schema(
  {
    email: {
      confirmationCode: { type: String, index: true },
      confirmationSentAt: { type: Date },
      confirmed: { type: Boolean, default: false },
    },
    password: {
      formattedKey: { type: String },
      hash: { type: String },
      resetCode: { type: String, index: true },
      sentAt: { type: Date },
    },
    shared: {
      avatarId: { type: String },
      bio: { type: String },
      canFollow: {type: Boolean},
      country: { type: String },
      coverId: { type: String },
      currency: { type: String, default: 'USD' },
      dob: { type: Date },
      email: { type: String, required: true, unique: true, index: true }, // <== Change to text?
      followers: { type: Number, default: 0},
      following: { type: Number, default: 0},
      fullName: { type: String }, // <== add index:text?
      gender: { type: String },
      isMe: {type: Boolean},
      language: { type: String, default: 'en' },
      location: { type: String },
      loggedIn: { type: Boolean, default: true },
      mobileCode: { type: String },
      mobileNumber: { type: String },
      twofactor: {type: Boolean, default: false},
      username: { type: String, unique: true, index: true }, // <== Change to text?
      warningMessage: { type: String, default: 'verify' },
      webSite: { type: String },
    },
  },
  {
    timestamps: true,
  }
);

data a sample as text

{ 
    "_id" : ObjectId("5e098adaf55332456cb733d8"), 
    "email" : {
        "confirmed" : false, 
        "confirmationCode" : "8f558eee9ac4e4119ec34c34fbe8e867c82a1b33"
    }, 
    "shared" : {
        "currency" : "USD", 
        "followers" : NumberInt(0), 
        "following" : NumberInt(0), 
        "language" : "en", 
        "loggedIn" : true, 
        "twofactor" : false, 
        "warningMessage" : "verify", 
        "email" : "[email protected]", 
        "fullName" : "Fred", 
        "username" : "Fred61", 
        "location" : "/my/profile"
    }, 
    "password" : {
        "hash" : "$2b$10$XFelKt9Gge6nF8lpwIMAYOPIfmaNyKAs0aR/VziX.v1rQ6ZVL0Bty", 
        "formattedKey" : "lmhc a5td smcr wolr wr3e 25fl 4rbr duu7"
    }, 
    "createdAt" : ISODate("2019-12-30T05:27:54.548+0000"), 
    "updatedAt" : ISODate("2019-12-30T09:02:45.808+0000"), 
    "__v" : NumberInt(0)
}

Upvotes: 1

Views: 240

Answers (1)

SuleymanSah
SuleymanSah

Reputation: 17858

Don't create the index with mongoose, mongoose isn't an index managemenet system.

Even in the docs they state this like this:

In a production environment, you should create your indexes using the MongoDB shell rather than relying on mongoose to do it for you.

So you can create all your indexes in mongodb shell like this:

db.users.createIndex(
   {
     "shared.username": "text",
     "shared.email": "text",
     "shared.fullName": "text",
   }
 )

db.users.createIndex( { "shared.username": 1 }, { unique: true } )
db.users.createIndex( { "shared.email": 1 }, { unique: true } )

// note that it is not a good idea to create unique index on fullname, since multiple users can have the same fullName.
//db.users.createIndex( { "shared.fullName": 1 }, { unique: true } )

db.users.createIndex({"email.confirmationCode" : 1})
db.users.createIndex({"password.resetCode" : 1})

This way you can remove all index and unique related options in your schema.

Upvotes: 1

Related Questions