Mongoose.js:按用户名LIKE值查找用户


94

我喜欢通过在mongoDb中寻找一个名为value的用户来寻找用户。问题在于:

username: 'peter'

是,如果用户名是“ Peter”或“ PeTER” ..或类似的名称,我找不到它。

所以我想做像SQL

SELECT * FROM users WHERE username LIKE 'peter'

希望你们能得到什么?

简写:mongoose.js / mongodb中的“字段喜欢值”


1
只是顺便说一句,在SQL查询将无法找到PeterPeTER无论是作为LIKE不区分大小写。
2012年

Answers:


143

对于那些正在寻找解决方案的人,这里是:

var name = 'Peter';
model.findOne({name: new RegExp('^'+name+'$', "i")}, function(err, doc) {
  //Do your action here..
});

2
“ i”自变量是什么意思?与区分大小写有关吗?
AzaFromKaza

2
“ i”是用于选择搜索标志的参数。那么“ i”是不区分大小写的。你可以在这里读更多关于它的内容。developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…–
PeterBechP

10
假设正则表达式无效。例如,如果您添加“ [”作为用户名,则会抛出异常。只需确保您先尝试捕获或重新指定输入,然后检查[^ a-zA-Z0-9],然后再继续即可。在这种情况下,它的公正测试输入是有意义的。
杰森·塞布林2014年

1
$ =匹配字符串的结尾
PeterBechP 2014年

1
@JasonSebring尽管我同意输入验证不是一个坏主意,但是最好的方法是实际的转义算法。例外甚至不是最严重的问题,但是可以想象您在登录页面上使用了类似的代码,并且输入".*"了一个用户名作为用户名。
Tobias 2014年

79

我最近对此有疑问,我使用此代码并为我正常工作。

var data = 'Peter';

db.User.find({'name' : new RegExp(data, 'i')}, function(err, docs){
    cb(docs);
});

使用直接/Peter/i工作,但我使用'/'+data+'/i'而不是为我工作。


好吧,我只是尝试了一下。我看到它还能找到我是否只写P ?? 嗯。
PeterBechP 2012年

是的,我使用Ajax请愿书来搜索用户。您可以修改RegExp。
Donflopez 2012年

35
db.users.find( { 'username' : { '$regex' : req.body.keyWord, '$options' : 'i' } } )

@MikeShi这样的示例场景是什么?
Len Joseph

@LenJoseph通常只是ReDoS攻击:owasp.org/index.php/…,我不知道猫鼬在这一点上是否容易受到攻击,或者是否有任何预期的功能来检测ReDoS输入并在猫鼬级别对其进行清理。
Mike Shi

14
collection.findOne({
    username: /peter/i
}, function (err, user) {
    assert(/peter/i.test(user.username))
})

如果值是var怎么办?如何设置?/ varhere / i?
PeterBechP 2012年

2
@PeterBechP构造一个正则表达式:\new RegExp(var, "i")
Raynos

工作正常..现在我有一个问题..如果var是peter,它只需要找到peter。但是,如果我将var设置为“ p”,它仍然会找到peter。
PeterBechP 2012年

@PeterBechP然后删除不区分大小写的标志:\
Raynos 2012年

14
router.route('/product/name/:name')
.get(function(req, res) {

    var regex = new RegExp(req.params.name, "i")
    ,   query = { description: regex };

    Product.find(query, function(err, products) {
        if (err) {
            res.json(err);
        }

        res.json(products);
    });

});  


9

猫鼬文档查找。正则表达式的mongodb doc。

var Person = mongoose.model('Person', yourSchema);
// find each person with a name contains 'Ghost'
Person.findOne({ "name" : { $regex: /Ghost/, $options: 'i' } },
    function (err, person) {
             if (err) return handleError(err);
             console.log('%s %s is a %s.', person.name.first, person.name.last, person.occupation);
});

请注意,我们传递给mongoose.findOne函数的第一个参数:{ "name" : { $regex: /Ghost/, $options: 'i' } }"name"是您要搜索的文档的字段,"Ghost"是正则表达式,"i"不区分大小写。希望这会帮助你。


什么是$ options
kabuto178 '18

8

以下查询将不敏感地以必需的字符串大小写查找文档,并且以全局形式出现

var name = 'Peter';
    db.User.find({name:{
                         $regex: new RegExp(name, "ig")
                     }
                },function(err, doc) {
                                     //Your code here...
              });

6

这就是我正在使用的。

module.exports.getBookByName = function(name,callback){
    var query = {
            name: {$regex : name}
    }
    User.find(query,callback);
}

5

这是我的expressJS代码:

router.route('/wordslike/:word')
    .get(function(request, response) {
            var word = request.params.word;       
            Word.find({'sentence' : new RegExp(word, 'i')}, function(err, words){
               if (err) {response.send(err);}
               response.json(words);
            });
         });

1

如果我想查询某些条件下的所有记录,可以使用以下方法:

if (userId == 'admin')
  userId = {'$regex': '.*.*'};
User.where('status', 1).where('creator', userId);

似乎不必要地使用了$regex您本该使用的时间{ $exists: true }
肖恩

0

只是补充@PeterBechP的答案。

不要忘记转义特殊字符。 https://stackoverflow.com/a/6969486

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

var name = 'Peter+with+special+chars';

model.findOne({name: new RegExp('^'+escapeRegExp(name)+'$', "i")}, function(err, doc) {
  //Do your action here..
});

0

这是我的转换解决方案的每一个值req.body的猫鼬LIKE PARAM:

let superQ = {}

Object.entries({...req.body}).map((val, i, arr) => {
    superQ[val[0]] = { '$regex': val[1], '$options': 'i' }
})

User.find(superQ)
  .then(result => {
    res.send(result)})
  .catch(err => { 
    res.status(404).send({ msg: err }) })
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.