【问题标题】:Search query with mongodb returns one result using $or使用 mongodb 的搜索查询使用 $or 返回一个结果
【发布时间】:2019-12-22 20:26:46
【问题描述】:

我正在尝试使用 javascript 查询我的 MongoDB,但是当我应该使用 $or 时,我似乎得到了一个结果。

我打算从前端接收一个字符串。我的逻辑是通过空格split 字符串并搜索字符串是否与数据库中的任何技能、位置和名称匹配。例如,如果用户搜索 PHP,它应该将所有具有 PHP 的用户作为一项技能,即使该用户具有其他技能。下面是代码

数据

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

代码

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);
  }  
};

假设我搜索PHP,我应该得到两个用户。这行得通。

但如果我用“PHP me”搜索,我会得到 ​​p>

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

而不是两个用户,因为他们的技能数组中都有php。请问,可能是什么问题,我该如何解决。

【问题讨论】:

    标签: javascript regex express mongoose


    【解决方案1】:

    为什么您不在查询中使用$regex

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

    上面的查询会给你一个想要的结果。

    【讨论】:

    • 不起作用。如果我搜索“PHP javascript”,我仍然只获得技能中同时包含 PHP 和 javascript 的数据,而不是两个用户,因为他们都具有 PHP 技能
    • 我注意到如果我搜索“javascript php”,两个结果都会出现,但如果我搜索“php javascript”,只有具有 php 和 javascript 技能的用户会出现
    • 为什么不在 robo3t 或任何其他工具上试试这个查询
    【解决方案2】:

    因为您在循环中重新分配了result,所以只有最后一个查询的结果才会出现。

    您可以使用正则表达式通过一个查询来解决您的问题:

    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);
      }  
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-13
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      • 2019-04-14
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      相关资源
      最近更新 更多