Nithin Sai
Nithin Sai

Reputation: 1013

How to show suggestions in MongoDB find()

I'm using mongoDB Atlas to store some data. The collection is like,

var User = new Schema({
    firstname: {
        type: String,
        default: ''
    },
    lastname: {
        type: String,
        default: ''
    }
}, {
    timestamps: true
});

But I'm using Passport for authentication, username and password is handled by it.

When searching for users by username, I want to display a list of usernames with matching characters. Like, auto complete suggestions.

I realize I have to use regex in some way to achieve this, but I don't know how! For now, I'm doing this,

router.post('/search', corsWithOptions, (req, res, next) => {
  User.findByUsername(req.body.username).then(user => {
    console.log(user);
    res.json(user)
  })
})

But until the entire username is available, this method returns null. Here, findByUsername is a method in Passport, takes 2 params (username, selectHashSaltFields).

I also tried this,

    User.find({
      $or: [
        {
          username: { '$regex': '.*' + req.body.search, $options: 'i' },
          firstname: { '$regex': '.*' + req.body.search, $options: 'i' },
          lastname: { '$regex': '.*' + req.body.search, $options: 'i' }
        }
      ]
    }).then(user => {
      console.log(user)
    })

This is returning an empty list, even when the values exist

This is a MERN stack, how to query documents and show suggestions for auto complete in frontend?

Upvotes: 2

Views: 1163

Answers (1)

Demo - https://mongoplayground.net/p/HNq6Vno-FPM

$or

db.collection.find({
  $or: [
    { username: { "$regex": ".*abc", "$options": "i" } },
    { firstname: { "$regex": ".*abc", "$options": "i" } },
    { lastname: { "$regex": ".*abc", "$options": "i" } }
  ]
}, { username: 1, lastname: 1, firstname: 1 }) // project only  if you want ignore _id also use _id: 0

Create Text Indexes and use $text for search.

db.user.createIndex({ username: "text", firstname : "text", lastname : "text" });

db.user.find({ $text: { $search: "abc" } } );
db.user.find({ $text: { $search: "/TuShAr/i" } });

Upvotes: 2

Related Questions