Mongoose.js : 사용자 이름 LIKE 값으로 사용자 찾기


94

나는 값이라는 사용자를 찾아서 mongoDb에서 사용자를 찾고 싶습니다. 문제 :

username: 'peter'

사용자 이름이 "Peter", "PeTER".. 또는 그와 비슷한 경우에는 찾을 수 없다는 것입니다.

그래서 나는 SQL처럼하고 싶다.

SELECT * FROM users WHERE username LIKE 'peter'

너희들이 내가 원하는 것을 얻길 바래?

Short : mongoose.js / mongodb의 'field LIKE value'


1
제쳐두고 SQL 쿼리는 대소 문자를 구분하지 Peter않거나 PeTER둘 중 하나를 찾지 LIKE못합니다.
beny23

답변:


143

여기에서 해결책을 찾고 있던 사람들을 위해 다음과 같습니다.

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 2013 년

10
이것은 정규식이 유효하지 않다고 가정합니다. 예를 들어 "["를 사용자 이름으로 추가하면 예외가 발생합니다. 입력을 먼저 시도하거나 정규식을 사용하고 [^ a-zA-Z0-9]를 확인한 다음 진행하지 않는지 확인하십시오. 이 경우 단지 테스트 입력이므로 의미가 있습니다.
Jason Sebring 2014 년

1
$ = 문자열 끝 일치
PeterBechP 2014

1
@JasonSebring 입력 유효성 검사가 나쁜 생각이 아니라는 데 동의하지만 가장 좋은 방법은 실제 이스케이프 알고리즘입니다. 예외도 최악의 문제는 아니지만 로그인 페이지에서 유사한 코드를 사용 ".*"하고 사용자 이름으로 입력 한 사용자를 상상해보십시오 .
Tobias

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를 수정할 수 있습니다.
Donflopez

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

@MikeShi 이것의 예제 시나리오는 무엇입니까?
Len Joseph

@LenJoseph는 일반적으로 ReDoS 공격 : owasp.org/index.php/… ,이 시점에서 몽구스가 취약한 지 또는 ReDoS 입력을 감지하고 몽구스 수준에서 삭제하는 기능이 있는지 알지 못합니다.
Mike Shi

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

값이 var이면 어떨까요? 설정하는 방법? / varhere / i?
PeterBechP

2
\ : 정규 표현식 구성 @PeterBechPnew RegExp(var, "i")
Raynos

잘 작동합니다 .. 이제 문제가 생겼습니다. var가 peter 인 경우에만 peter를 찾아야합니다. 그러나 var를 'p'로 설정하면 여전히 peter를 찾을 수 있습니다.
PeterBechP 2012 년

@PeterBechP 다음 소문자 구분 플래그를 제거 : \
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

이를 위해 정규식을 사용해야합니다.

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

하지만이 쿼리는 인덱스를 사용하지 않습니다.


9

찾기위한 몽구스 문서. 정규식에 대한 mongodb 문서.

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

이것은 req.body의 모든 값 을 mongoose LIKE param으로 변환하는 솔루션입니다 .

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 }) })
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.