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


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

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.


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

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

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

});  

13

Anda harus menggunakan regex untuk itu.

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

Berhati-hatilah, meskipun kueri ini tidak menggunakan indeks.


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.


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

6

Inilah yang saya gunakan.

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

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

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

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

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 }) })
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.