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


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

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.


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

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

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

});  

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.


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.


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

6

Das benutze ich.

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

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

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

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

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 }) })
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.