9
mongoose: 5.8.9
node: v12.13.0

After setting up to create index on the schema, mongoose doesn't create the index, After creating a new document there is only ID index nothing newly created. I had done as the document mentioned for creating index but still I can't figure out where I'm making the mistake.

When

 const ads = await Ad.find({ $text: { $search: "something" } })

Error

MongoError: text index required for $text query
    at Connection.<anonymous> (/home/usama/Projects/commercial/adex/node_modules/mongoose/node_modules/mongodb/lib/core/connection/pool.js:466:61)
    at Connection.emit (events.js:210:5)
    at Connection.EventEmitter.emit (domain.js:476:20)
    at processMessage (/home/usama/Projects/commercial/adex/node_modules/mongoose/node_modules/mongodb/lib/core/connection/connection.js:384:10)
    at Socket.<anonymous> (/home/usama/Projects/commercial/adex/node_modules/mongoose/node_modules/mongodb/lib/core/connection/connection.js:553:15)
    at Socket.emit (events.js:210:5)
    at Socket.EventEmitter.emit (domain.js:476:20)
    at addChunk (_stream_readable.js:308:12)
    at readableAddChunk (_stream_readable.js:289:11)
    at Socket.Readable.push (_stream_readable.js:223:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:182:23) {
  ok: 0,
  errmsg: 'text index required for $text query',
  code: 27,
  codeName: 'IndexNotFound',
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {}
}

My schema

import { Schema } from 'mongoose'
import mongoosePaginate from 'mongoose-paginate-v2'
import Local from '../index'

const adSchema = new Schema(
  {
    id: Schema.Types.ObjectId,
    creater: Schema.Types.ObjectId,
    title: { type: String },
    tags: Array,
    description: { type: String, maxlength: 4500, },
  },
  {
    timestamps: true,
    versionKey: false,
    autoIndex: false
  }
)

adSchema.index({ title: 'text', description: 'text', tags: 'text' })
adSchema.plugin(mongoosePaginate)

const Ad = Local.model('Ad', adSchema)

export { Ad as default }

On mongo shell

> myads.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "adex.ads"
    }
]

U.A
  • 2,991
  • 3
  • 24
  • 36
  • In your `My schema` what is `Local` ? This `const Ad = Local.model('Ad', adSchema)` has to be `import { Schema, mongoose } from 'mongoose'; const Ad = mongoose.model('Ad', adSchema)` – whoami - fakeFaceTrueSoul Jan 26 '20 at 19:09
  • On my server, I run two separate MongoDB database, Local runs store data on server remote store on MongoDB atlas – U.A Jan 27 '20 at 00:56
  • 1
    : Mickl is right, you need to remove autoIndex:false - usually you would enable it for prod servers, I’ve observed it.. – whoami - fakeFaceTrueSoul Jan 27 '20 at 00:59

3 Answers3

8

Below line:

adSchema.index({ title: 'text', description: 'text', tags: 'text' })

correctly defines an index on mongoose schema (not on a database). By default mongoose creates indexes when your application starts up (link) however you're preventing it by using autoIndex: false.

So you have to either remove that line or run createIndexes on your model explicitly:

adSchema.index({ title: 'text', description: 'text', tags: 'text' });
const Ad = Local.model('Ad', adSchema);
Ad.createIndexes();
mickl
  • 48,568
  • 9
  • 60
  • 89
  • Thanks a lot this creates the `text` index, And what should I do in prod env? should I remove `Ad.createIndexes();` or keep it. – U.A Jan 27 '20 at 01:07
  • 2
    You can run a one-time script and create all the indexes if you want to have full control over that process or keep Mongoose's autoindexing - it really depends on the deployment strategy you and your organization have – mickl Jan 27 '20 at 01:10
5

This is how you resolve the same using MongoDB Compass application instead using the mongo console.

Connect to the DB using a connection string like this

mongodb://<user>:<password>@<ip>:<port>/<your db>?authSource=<user>&readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false

Then select the correct collection from the left pane and then select Indexes tab and create the text index like shown below

enter image description here

SajithP
  • 592
  • 8
  • 19
3

The best method for me that woks with no warning is from mongodb could

1

2

and from code you need to pass :>>

const blogPosts = await BlogPostModel.find({  $text: { $search: `"${req.query["your-search-query"] }"`  } })
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Mahdi-Soultana
  • 144
  • 1
  • 9