Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 대소문자를 구분하지 않는 검색하는 방법 ($regex 완벽 가이드)

MongoDB에서는 $regex 연산자를 활용하면 대소문자를 구분하는 검색 조건을 손쉽게 설정할 수 있습니다. 특히 정규식에 i 옵션(플래그)을 추가하면 대소문자를 구분하지 않는(case-insensitive) 검색도 가능합니다.

기본 문법

가장 기본적인 정규식 검색 문법은 다음과 같습니다.

db.yourCollectionName.find({"yourFieldName" : { '$regex':'^yourValue$'}});

슬래시(/) 표기법을 사용한 또 다른 방식도 있습니다. 마지막의 i 플래그가 대소문자를 무시하도록 만들어 줍니다.

db.yourCollectionName.find({"Name" : { '$regex':/^yourValue$/i}});

예제 컬렉션 생성하기

개념을 이해하기 위해 샘플 문서가 포함된 컬렉션을 먼저 생성해 보겠습니다. 아래 쿼리로 컬렉션을 만들고 문서를 삽입합니다.

> db.caseInsesitiveDemo.insertOne({"Name":"John"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c8bd66293c80e3f23815e83")
}
> db.caseInsesitiveDemo.insertOne({"Name":"Johnson"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c8bd66693c80e3f23815e84")
}
> db.caseInsesitiveDemo.insertOne({"Name":"Johny"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c8bd66a93c80e3f23815e85")
}

저장된 문서 확인하기

find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.

> db.caseInsesitiveDemo.find().pretty();

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5c8bd66293c80e3f23815e83"), "Name" : "John" }
{ "_id" : ObjectId("5c8bd66693c80e3f23815e84"), "Name" : "Johnson" }
{ "_id" : ObjectId("5c8bd66a93c80e3f23815e85"), "Name" : "Johny" }

일반적인 정규식 검색

아래처럼 앵커(^, $) 없이 정규식을 사용하면 'John'이 포함된 모든 문서가 조회됩니다.

> db.caseInsesitiveDemo.find({"Name" : { '$regex' : 'John' }});

실행 결과:

{ "_id" : ObjectId("5c8bd66293c80e3f23815e83"), "Name" : "John" }
{ "_id" : ObjectId("5c8bd66693c80e3f23815e84"), "Name" : "Johnson" }
{ "_id" : ObjectId("5c8bd66a93c80e3f23815e85"), "Name" : "Johny" }

'John', 'Johnson', 'Johny' 세 개의 문서가 모두 출력되는 것을 확인할 수 있습니다. 이는 부분 일치(partial match) 검색이기 때문입니다.

Case 1: 정확히 일치하는 값만 조회하기

다른 유사한 문서들은 제외하고 정확히 일치하는 값만 조회하고 싶다면 ^(시작)와 $(끝) 앵커를 사용한 첫 번째 쿼리를 활용하세요.

> db.caseInsesitiveDemo.find({"Name" : { '$regex':'^John$'}});

실행 결과:

{ "_id" : ObjectId("5c8bd66293c80e3f23815e83"), "Name" : "John" }

위 출력 결과를 보면 'John'이라는 문서만 정확하게 조회된 것을 확인할 수 있습니다.

Case 2: 대소문자를 구분하지 않고 정확히 일치하는 값 조회하기

대소문자와 관계없이 정확히 일치하는 값을 찾으려면 두 번째 쿼리처럼 i 플래그를 추가하면 됩니다.

> db.caseInsesitiveDemo.find({"Name" : { '$regex':/^John$/i}});

실행 결과:

{ "_id" : ObjectId("5c8bd66293c80e3f23815e83"), "Name" : "John" }

이처럼 i 옵션을 사용하면 'john', 'JOHN', 'JoHn' 등 어떤 대소문자 조합으로 저장되어 있더라도 동일하게 매칭됩니다.

정리

  • $regex: MongoDB에서 정규식 기반 검색을 지원하는 연산자
  • ^값$: 문자열의 시작과 끝을 고정하여 정확히 일치하는 값만 매칭
  • i 플래그: 대소문자를 구분하지 않는 검색을 가능하게 하는 옵션

참고로 대량의 데이터에서 자주 대소문자 무시 검색을 수행한다면, 인덱스 성능을 위해 대소문자를 구분하지 않는(collation strength 1 또는 2) 컬렉션 설정을 고려하는 것도 좋은 방법입니다.