Home > Software design >  Mongoose $search returning empty array
Mongoose $search returning empty array

Time:04-22

I'm getting an empty array when using $search in mongoose.

Schema

const mongoose = require('mongoose');

const studentSchema = new mongoose.Schema({
  name: { type: String },
});

studentSchema.index({ name: 'text' });

const Student = mongoose.model('Student', studentSchema);
module.exports = Student;

$search

const Student = require('../models/Student.Model');
(async () => {
    const result = await Student.aggregate([
           {
        $search: {
          index: 'default',
          compound: {
            must: [
              {
                text: {
                  query: 'Lee',
                  path: 'name',
                  fuzzy: {
                     maxEdits: 1,
                  },
                },
              },
            ],
          },
        },
      },
    ]);

})();

This gives me an empty array. So I tried another syntax.

const result = await Student.aggregate().search({
      index: 'default',
      compound: {
        must: [
          {
            text: {
              query: 'Lee',
              path: 'name',
              fuzzy: {
                maxEdits: 1,
              },
            },
          },
        ],
      },
    });

That also gave me an empty array.

To test whether the model was working I used find and filter, and could see similar results I'd expect to see with $search.

let result2 = await Student.find({});

result2 = result2.filter((p) => p.name.includes('Lee'));
    

result2 had two documents

result2:  [
  { _id: 625f70ac90e916620045cab5, name: 'Brian Lee', __v: 0 },
  { _id: 625f70e39660b486c82b2011, name: 'Lee Cohen', __v: 0 }
]

Update: find and $text also give me the above correct results, but I want to implement a fuzzy search and I don't think you can with find and $text`:

const resultsShort = await Student.find({ $text: { $search: 'Lee' } });

Why isn't $search returning these two documents?

CodePudding user response:

This creates a $text index not an Atlas Search index:

studentSchema.index({ name: 'text' });

The above can be removed.

You can't create an Atlas Search index on a mongoose schema, it has to be set on the Atlas site or the CLI.

To create an Atlas Search index, go to your database on cloud.mongodb.com ->Search-->Create Search Index-->JSON Editor-->Next-->pick your collection--> set the index name. here it would be 'default'

Then set the index:

{ 
  "mappings": {
    "dynamic":false,
    "fields":{
    "name":{
    "analyzer":"lucene.standard",
    "type":"string"
    }
  }
}

Then this code works.

const result = await Student.aggregate().search({
      index: 'default',
      compound: {
        must: [
          {
            text: {
              query: 'Lee',
              path: 'name',
              fuzzy: {
                maxEdits: 1,
              },
            },
          },
        ],
      },
    });
    ```

CodePudding user response:

Use $regex

db.collection.find({
  name: {
    $regex: "Lee"
  }
})

mongoplayground


createIndex

db.collection.createIndex({name:"text"})

text search

db.collection.find({$text: {$search: "Lee"}})
  • Related