简体   繁体   中英

Search query with mongodb returns one result using $or

I am trying to query my MongoDB with javascript but I seem to get one result when I'm supposed to using the $or .

I am meant to receive a string form the frontend. My logic was to split the string by spaces and search if the string matches any of the skill, location, and name in the database. For example, if a user searches PHP it should bring all users with PHP as a skill even if the user has another skill. Below is the code

data

{
    "_id":"1",
    "skills": ["PHP"],
    "name":"You"
}
{
    "_id":"2",
    "skills": ["PHP", "Javascript"],
    "name":"Me"
}

the code

exports.search = async (req, res, next) => {
  try {
    const escapeChar = escapeString(req.body.query);
    const searchQueries = escapeChar.split(' ');
    let result;
    for (let i in searchQueries) {
      const ret = async () => {
        const pattern = new RegExp(searchQueries[i], 'gi');
        const user = await User.find({
          $or: [{ name: pattern }, { skills: pattern }],
        });
        return user;
      };
      result = await ret();
    }
    if (result.length > 0) {
      return res.json(sendResponse(httpStatus.OK, 'User found', result));
    }
    return res.json(sendResponse(httpStatus.NOT_FOUND, 'User not found'));
  } catch (error) {
      next(error);
  }  
};

Say I search PHP , I should get both users. This works.

But if I search with 'PHP me' i get

{
    "_id":"2",
    "skills ["PHP", "Javascript"],
    "name":"Me"
}

instead of both users since the both have php in their skills array. Please, what could be the issue and how do i solve this.

Why you don't use $regex in your query.

db.getCollection('tests').find({
    $or: [{
        name: {
            $regex: /Me$/
        }
    }, {
        skills: {
            $regex: /PHP$/
        }
    }]
});

Above query will give you a desire result.

Because you reassign your result in the loop so only the result of the last query come.

You can solve your problem with one query using regex:

exports.search = async (req, res, next) => {
  try {
    const escapeChar = escapeString(req.body.query);
    const searchQueries = escapeChar.split(' ');

    const pattern = new RegExp(`(${searchQueries.join("|")})`, 'i');
    const users = await User.find({
      $or: [{ name: pattern }, { skills: pattern }],
    });

    // In case the above not works
    const pattern = new RegExp(`(${searchQueries.join("|")})`);
    const users = await User.find({
      $or: [
        {name: {$regex: pattern, $options: "i" }}, 
        {skills: {$regex: pattern, $options: "i" }}
      ],
    });

    if (users.length > 0) {
      return res.json(sendResponse(httpStatus.OK, 'User found', users));
    }
    return res.json(sendResponse(httpStatus.NOT_FOUND, 'User not found'));
  } catch (error) {
    next(error);
  }  
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM