Mongoose.js: Знайти користувача за іменем користувача, як значення


95

Мені подобається шукати користувача в mongoDb, шукаючи користувача, якого називають value. Проблема з:

username: 'peter'

полягає в тому, що я не знаходжу його, якщо ім'я користувача "Peter", "PeTER" .. або щось подібне.

Тому я хочу робити як sql

SELECT * FROM users WHERE username LIKE 'peter'

Сподіваюся, ви, хлопці, отримаєте те, про що їх просять?

Коротке: 'поле LIKE value' у mongoose.js / mongodb


1
Окрім того, запит SQL не буде знайдений, Peterабо PeTERяк LIKEтакий, що не враховує регістр.
beny23

Відповіді:


144

Для тих, хто шукав рішення тут:

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

2
що означає аргумент "i"? Чи це пов’язано з чутливістю до регістру?
AzaFromKaza

2
"i" - це аргумент для вибору прапора пошуку. "i" тоді не враховує регістр. Детальніше про це ви можете прочитати тут. developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
PeterBechP

10
Це передбачає, що регулярний вираз не є недійсним. Якщо ви додасте "[" як ім'я користувача, наприклад, викине виняток. Просто переконайтеся, що ви або спробували перехопити, або змінити регулярний вираз, і перевірили наявність [^ a-zA-Z0-9], а потім не продовжували. У цьому випадку його просто тестове введення має сенс.
Джейсон Себрінг,

1
$ = Збіг кінця рядка
PeterBechP

1
@JasonSebring Хоча я згоден, що перевірка вводу - це не погана ідея, найкращий підхід - це фактичний алгоритм екранування. І винятки - це навіть не найгірша проблема, але уявіть, що ви використовували подібний код на сторінці входу, а користувача вводили ".*"як ім’я користувача.
Тобіас,

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.
Донфлопес,

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

@MikeShi Який приклад цього може бути?
Лен Джозеф

@LenJoseph - загалом атака ReDoS: owasp.org/index.php/… , я не знаю, чи є mongoose вразливим на даний момент, чи є якась передбачувана функціональність для виявлення входів ReDoS та дезінфекції їх на рівні mongoose.
Mike Shi

14
collection.findOne({
    username: /peter/i
}, function (err, user) {
    assert(/peter/i.test(user.username))
})

а якщо значення - це var? Як це налаштувати? / varhere / i?
PeterBechP

2
@PeterBechP побудуйте регулярний вираз: \new RegExp(var, "i")
Raynos 22.03.12

відмінно працює .. тепер у мене проблема .. Знайти Пітера потрібно лише у випадку, якщо var є пітером. Але якщо я встановлю для var значення "p", він все одно знайде Пітера.
PeterBechP

Потім @PeterBechP видаляє прапор чутливості до регістру: \
Райнос

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 doc для регулярного виразу.

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"для випадку нечутливого матчу. Сподіваюся, це допоможе вам.


які $ варіанти
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

Це моє рішення для перетворення кожного значення в потрібному тілі в параметр мангуста 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 }) })
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.