Mongoose.js:ユーザー名LIKE値でユーザーを検索


94

私は値と呼ばれるユーザーを探してmongoDbでユーザーを見つけに行きたいです。の問題:

username: 'peter'

ユーザー名が「Peter」、「PeTER」、またはそのような場合、私はそれを見つけられないということです。

だから私はSQLのようにしたい

SELECT * FROM users WHERE username LIKE 'peter'

あなたは私が何のために何を得るのを願っていますか?

Short:mongoose.js / mongodbの「フィールドLIKE値」


1
余談ですが、SQLクエリは大文字と小文字を区別しないため、PeterまたはPeTERどちらも検出しLIKEません。
beny23 2012年

回答:


143

ここで解決策を探していた人のためにそれは:

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

2
「i」の引数はどういう意味ですか?大文字と小文字の区別に関係がありますか?
AzaFromKaza 2013

2
「i」は、検索フラグを選択するための引数です。「i」は大文字と小文字を区別しません。詳しくはこちらをご覧ください。developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/...
PeterBechP

10
これは、正規表現が無効でないことを前提としています。たとえば、ユーザー名として「[」を追加すると、例外がスローされます。事前に入力を再試行または再正規化し、[^ a-zA-Z0-9]を確認してから続行しないことを確認してください。この場合、そのテスト入力だけが理にかなっています。
Jason Sebring 2014年

1
$ =文字列の末尾に一致
PeterBechP '29

1
@JasonSebring入力の検証は悪い考えではないことに同意しますが、最良のアプローチは実際のエスケープアルゴリズムです。また、例外は最悪の問題でさえありませんが、ログインページで同様のコードを使用".*"し、ユーザーをユーザー名として入力したとします。
Tobias

79

私は最近これで問題がありました、私はこのコードを使用して私のためにうまくいきます。

var data = 'Peter';

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

直接/Peter/i作業を使用しますが、私は使用し'/'+data+'/i'、私のためには機能しません。


さて、私はそれをもう少し試してみました。私がPと書いているかどうかもわかりますか?うーん。
PeterBechP

はい、私はユーザーを検索するajax請願に使用します。RegExpを変更できます。
Donflopez

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

@MikeShiこれのシナリオ例は何ですか?
レンジョセフ

@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

2
\:正規表現構築@PeterBechPnew RegExp(var, "i")
レイノス

正常に動作します。今、問題が発生しました。varがピーターの場合にのみピーターを見つける必要があります。しかし、varを「p」に設定しても、ピーターが見つかります。
PeterBechP

@PeterBechPは、大文字小文字を区別しないフラグを削除します:\
Raynos

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

});  

13

そのためには正規表現を使用する必要があります。

db.users.find({name: /peter/i});

ただし、このクエリはインデックスを使用しないことに注意してください。


9

検索用のマングースのドキュメント。正規表現のmongodbドキュメント。

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

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パラメータに変換するための私のソリューションです。

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 }) })
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.