Mongoose.js: Temukan pengguna berdasarkan nama pengguna LIKE

95

Saya ingin mencari pengguna di mongoDb dengan mencari pengguna yang disebut nilai. Masalah dengan:

username: 'peter'

adalah saya tidak menemukannya jika nama penggunanya adalah "Peter", atau "PeTER" .. atau semacamnya.

Jadi saya ingin melakukan seperti sql

SELECT * FROM users WHERE username LIKE 'peter'

Semoga kalian mendapatkan apa yang saya minta?

Singkat: 'field LIKE value' di mongoose.js / mongodb

PeterBechP
sumber
1
Selain itu, kueri SQL tidak akan menemukan Peteratau PeTERkarena LIKEtidak peka huruf besar / kecil.
beny23

Jawaban:

144

Bagi mereka yang sedang mencari solusi, ini dia:

var name = 'Peter';
model.findOne({name: new RegExp('^'+name+'$', "i")}, function(err, doc) {
  //Do your action here..
});
PeterBechP
sumber
2
apa artinya argumen "i"? Apakah ini ada hubungannya dengan sensitivitas huruf?
AzaFromKaza
2
"i" adalah argumen untuk memilih bendera pencarian. "i" maka untuk case-insensitive. Anda dapat membaca lebih lanjut di sini. developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
PeterBechP
10
Ini mengasumsikan regex tidak valid. Jika Anda menambahkan "[" sebagai nama pengguna misalnya, akan memunculkan pengecualian. Pastikan Anda mencoba menangkap atau mengubah kualitas masukan Anda sebelumnya dan memeriksa [^ a-zA-Z0-9] lalu tidak melanjutkan. Dalam hal ini, input tes saja jadi masuk akal.
Jason Sebring
1
$ = Cocokkan akhir string
PeterBechP
1
@JasonSebring Meskipun saya setuju bahwa validasi input bukanlah ide yang buruk, pendekatan terbaik adalah algoritma pelolosan yang sebenarnya. Dan pengecualian bahkan bukan masalah terburuk, tetapi bayangkan Anda menggunakan kode serupa pada halaman login dan pengguna memasukkan ".*"nama pengguna.
Tobias
79

Saya mengalami masalah dengan ini baru-baru ini, saya menggunakan kode ini dan berfungsi dengan baik untuk saya.

var data = 'Peter';

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

Gunakan langsung /Peter/ibekerja, tetapi saya menggunakan '/'+data+'/i'dan tidak bekerja untuk saya.

Donflopez
sumber
Yah, saya baru saja mencobanya lagi. Saya melihatnya juga menemukan jika saya hanya menulis P ?? hmmm.
PeterBechP
Ya, saya menggunakan petisi ajax untuk mencari pengguna. Anda dapat mengubah RegExp.
Donflopez
36
db.users.find( { 'username' : { '$regex' : req.body.keyWord, '$options' : 'i' } } )
Kanomdook
sumber
@MikeShi Apa contoh skenario ini?
Len Joseph
@LenJoseph hanya secara umum serangan ReDoS: owasp.org/index.php/… , saya tidak menyadari jika luwak rentan pada saat ini, atau jika ada fungsi yang dimaksudkan untuk mendeteksi masukan ReDoS dan membersihkannya di tingkat luwak.
Mike Shi
14
collection.findOne({
    username: /peter/i
}, function (err, user) {
    assert(/peter/i.test(user.username))
})
Raynos
sumber
bagaimana jika nilainya adalah var? Bagaimana cara mengaturnya? / varhere / i?
PeterBechP
2
@PeterBechP membuat ekspresi reguler: \new RegExp(var, "i")
Raynos
berfungsi dengan baik .. sekarang saya mendapat masalah .. Itu hanya harus menemukan peter jika var adalah peter. Tetapi jika saya mengatur var ke 'p' itu masih akan menemukan peter.
PeterBechP
@PeterBechP kemudian hapus tanda case insensitivity: \
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);
    });

});  
victorkurauchi
sumber
13

Anda harus menggunakan regex untuk itu.

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

Berhati-hatilah, meskipun kueri ini tidak menggunakan indeks.

Sergio Tulentsev
sumber
9

dokter luwak untuk menemukan. mongodb doc untuk regex.

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

Catatan argumen pertama kami lolos ke mongoose.findOnefungsi: { "name" : { $regex: /Ghost/, $options: 'i' } }, "name"adalah bidang dokumen yang Anda cari, "Ghost"adalah ekspresi reguler, "i"adalah untuk kasus pertandingan sensitif. Semoga ini bisa membantu Anda.

Shashith Darshana
sumber
apa saja $ options
kabuto178
8

Kueri berikut akan menemukan dokumen dengan string case yang diperlukan secara tidak sensitif dan dengan kejadian global juga

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

Inilah yang saya gunakan.

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

Berikut kode saya dengan 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);
            });
         });
Enrico Giurin
sumber
1

jika saya ingin menanyakan semua rekaman pada beberapa kondisi, saya dapat menggunakan ini:

if (userId == 'admin')
  userId = {'$regex': '.*.*'};
User.where('status', 1).where('creator', userId);
maverick
sumber
Sepertinya penggunaan yang tidak perlu $regexsaat Anda bisa saja menggunakannya { $exists: true }.
sean
0

Hanya melengkapi jawaban @PeterBechP.

Jangan lupa untuk menggambar karakter khusus. 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..
});
felipepastorelima
sumber
0

Ini adalah solusi saya untuk mengubah setiap nilai dalam req.body menjadi parameter SUKA luwak :

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 }) })
Solomon Bush
sumber