Mongoose.js: Benutzer anhand des Benutzernamens LIKE value suchen

94

Ich suche gerne einen Benutzer in mongoDb, indem ich nach einem Benutzer namens value suche. Das Problem mit:

username: 'peter'

ist, dass ich es nicht finde, wenn der Benutzername "Peter" oder "PeTER" ist .. oder so ähnlich.

Also möchte ich SQL mögen

SELECT * FROM users WHERE username LIKE 'peter'

Hoffe ihr bekommt was ich verlange?

Kurz: 'Feld LIKE Wert' in mongoose.js / mongodb

PeterBechP
quelle
1
Abgesehen davon würde die SQL-Abfrage nicht finden Peteroder auch PeTERnicht, da die LIKEGroß- und Kleinschreibung nicht berücksichtigt wird.
Beny23

Antworten:

143

Für diejenigen, die hier nach einer Lösung suchen, ist es:

var name = 'Peter';
model.findOne({name: new RegExp('^'+name+'$', "i")}, function(err, doc) {
  //Do your action here..
});
PeterBechP
quelle
2
Was bedeutet "i" -Argument? Hat es etwas mit Groß- und Kleinschreibung zu tun?
AzaFromKaza
2
"i" ist ein Argument für die Auswahl eines Suchflags. "i" ist dann für Groß- und Kleinschreibung nicht. Hier können Sie mehr darüber lesen. developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
PeterBechP
10
Dies setzt voraus, dass der reguläre Ausdruck nicht ungültig ist. Wenn Sie beispielsweise "[" als Benutzernamen hinzufügen, wird eine Ausnahme ausgelöst. Stellen Sie einfach sicher, dass Sie versuchen, Ihre Eingabe zu fangen oder erneut zu regulieren, bevor Sie nach [^ a-zA-Z0-9] suchen, und fahren Sie dann nicht fort. In diesem Fall ist die reine Testeingabe also sinnvoll.
Jason Sebring
1
$ = Match das Ende der Zeichenfolge
PeterBechP
1
@JasonSebring Obwohl ich der Meinung bin, dass die Validierung von Eingaben keine schlechte Idee ist, ist der beste Ansatz ein tatsächlicher Escape-Algorithmus. Und Ausnahmen sind nicht einmal das schlimmste Problem. Stellen Sie sich jedoch vor, Sie haben auf einer Anmeldeseite einen ähnlichen Code verwendet und einen Benutzer ".*"als Benutzernamen eingegeben .
Tobias
79

Ich hatte kürzlich Probleme damit, ich benutze diesen Code und arbeite gut für mich.

var data = 'Peter';

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

Verwenden Sie direkt /Peter/iarbeiten, aber ich benutze '/'+data+'/i'und arbeite nicht für mich.

Donflopez
quelle
Nun, ich habe es einfach noch einmal versucht. Ich sehe es auch finden, wenn ich nur P schreibe? Hmmm.
PeterBechP
Ja, ich verwende für Ajax-Petitionen, um Benutzer zu suchen. Sie können das RegExp ändern.
Donflopez
35
db.users.find( { 'username' : { '$regex' : req.body.keyWord, '$options' : 'i' } } )
Kanomdook
quelle
@ MikeShi Was ist ein Beispielszenario dafür?
Len Joseph
@LenJoseph nur allgemein der ReDoS-Angriff: owasp.org/index.php/… , ich weiß nicht, ob Mungo zu diesem Zeitpunkt anfällig ist oder ob es beabsichtigte Funktionen gibt, um ReDoS-Eingaben zu erkennen und sie auf Mungo-Ebene zu bereinigen.
Mike Shi
14
collection.findOne({
    username: /peter/i
}, function (err, user) {
    assert(/peter/i.test(user.username))
})
Raynos
quelle
Was ist, wenn der Wert eine Variable ist? Wie richte ich das ein? / varhere / i?
PeterBechP
2
@ PeterBechP konstruieren einen regulären Ausdruck: \new RegExp(var, "i")
Raynos
funktioniert gut .. jetzt habe ich ein Problem .. Es muss nur Peter finden, wenn die Var Peter ist. Aber wenn ich die Variable auf 'p' setze, wird sie immer noch Peter finden.
PeterBechP
@ PeterBechP entfernen Sie dann das Flag für die Groß- und Kleinschreibung: \
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
quelle
13

Sie sollten dafür einen regulären Ausdruck verwenden.

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

Seien Sie jedoch vorsichtig, dass diese Abfrage keinen Index verwendet.

Sergio Tulentsev
quelle
9

Mungo doc zu finden. Mongodb Doc für 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);
});

Beachten Sie das erste Argument , das wir weitergeben mongoose.findOneFunktion: { "name" : { $regex: /Ghost/, $options: 'i' } }, "name"ist das Feld des Dokuments , das Sie suchen, "Ghost"ist der reguläre Ausdruck, "i"ist für Groß- und Kleinschreibung übereinstimmen. Hoffe das wird dir helfen.

Shashith Darshana
quelle
Was sind die $ Optionen
Kabuto178
8

Die folgende Abfrage findet die Dokumente mit der erforderlichen Zeichenfolge ohne Berücksichtigung der Groß- und Kleinschreibung und auch mit globalem Vorkommen

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

Das benutze ich.

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

Hier mein Code mit 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
quelle
1

Wenn ich alle Datensätze unter bestimmten Bedingungen abfragen möchte , Ich kann Folgendes verwenden:

if (userId == 'admin')
  userId = {'$regex': '.*.*'};
User.where('status', 1).where('creator', userId);
Einzelgänger
quelle
Scheint eine unnötige Verwendung zu sein, $regexwenn Sie gerade verwendet haben könnten { $exists: true }.
Sean
0

Ergänzt nur die Antwort von @PeterBechP.

Vergessen Sie nicht, die Sonderzeichen zu gestalten. 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
quelle
0

Dies ist meine Lösung, um jeden Wert in einem req.body in einen Mungo- LIKE- Parameter umzuwandeln:

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
quelle