정규식
참고
이 페이지에서는 자체 관리(비Atlas) 배포를 위한 일반 표현식 검색 역량에 대해 설명합니다. MongoDB Atlas에 호스팅된 데이터의 경우 MongoDB는 자체 $regex
연산자가 있는 향상된 전체 텍스트 검색 솔루션인 Atlas Search를 제공합니다. 자세히 알아보려면 Atlas Search 설명서에서 $regex를 참조하세요.
정의
호환성
다음 환경에서 호스팅되는 배포에 $regex
사용할 수 있습니다.
MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
구문
$regex
을 사용하려면 다음 구문 중 하나를 사용합니다:
{ <field>: { $regex: /pattern/, $options: '<options>' } } { "<field>": { "$regex": "pattern", "$options": "<options>" } } { <field>: { $regex: /pattern/<options> } }
참고
$regex
를 mongodump
와 함께 사용하려면 쿼리 문서를 작은따옴표('{ ... }')로 묶어 셸 환경과 상호 작용하지 않도록 해야 합니다.
쿼리 문서는 필드 이름과 연산자를 따옴표로 묶는 등 확장 JSON v2 형식 (완화 모드 또는 표준/엄격 모드)이어야 합니다. 예시:
mongodump -d=sample_mflix -c=movies -q='{"year": {"$regex": "20"}}'
MongoDB에서는 정규 표현식 객체를 사용하여(예: /pattern/
) 표현식을 지정합니다:
{ <field>: /pattern/<options> }
특정 구문 사용에 대한 제한 사항은 $정규식 대 /패턴/구문을 참조하세요.
다음은 <options>
정규 표현식에 사용할 수 있습니다.
옵션 | 설명 |
---|---|
i | 대소문자 구분 없이 대문자와 소문자를 일치시키기 위한 옵션입니다. 이에 대한 예시 대소문자를 구분하지 않는 정규식 일치 수행을 참조하세요. |
m | 앵커가 포함된 패턴의 경우(예: 여러 줄 값이 있는 문자열의 경우 시작은 패턴에 앵커가 포함되어 있지 않거나 문자열 값에 개행 문자가 없는 경우(예: |
x |
또한 이스케이프되지 않은 해시/파운드 (
|
s | 점 문자(예: . )를 사용하여 줄 바꿈 문자를 포함한 모든 문자를 일치시킵니다. 예는 . 점 문자를 사용하여 새 줄 일치하기를 참조하세요. |
u | 유니코드를 지원합니다. 이 플래그는 허용되지만 중복됩니다. UTF는 기본적으로 $regex 연산자에 설정되어 있으므로 u 옵션이 필요하지 않습니다. |
참고
$regex
연산자는 g
전역 검색 수정자를 지원하지 않습니다.
행동
정규식 대 /패턴/ 구문
$in
표현식
$in
쿼리 조건자 연산자에 정규 표현식을 포함하려면 JavaScript 정규 표현식 객체(/pattern/
)만 사용할 수 있습니다.
예를 들면 다음과 같습니다.
{ name: { $in: [ /^acme/i, /^ack/ ] } }
$in
연산자 내에서 $regex
연산자 표현식을 사용할 수 없습니다 .
필드에 대한 암시적 AND
조건
필드에 대한 쉼표로 구분된 쿼리 조건 목록에 정규 표현식을 포함하려면 $regex
연산자를 사용합니다. 예시:
{ name: { $regex: /acme.*corp/i, $nin: [ 'acmeblahcorp' ] } } { name: { $regex: /acme.*corp/, $options: 'i', $nin: [ 'acmeblahcorp' ] } } { name: { $regex: 'acme.*corp', $options: 'i', $nin: [ 'acmeblahcorp' ] } }
x
및 s
옵션
x
옵션 또는 s
옵션을 사용하려면 $regex
연산자 표현식을 $options
연산자와 함께 사용해야 합니다. 예를 들어 i
및 s
옵션을 지정하려면 두 옵션 모두에 $options
를 사용해야 합니다.
{ name: { $regex: /acme.*corp/, $options: "si" } } { name: { $regex: 'acme.*corp', $options: "si" } }
PCRE와 JavaScript 비교
JavaScript에서 지원되지 않는 표현식에서 PCRE 지원 기능을 사용하려면 $regex
연산자를 사용하고 표현식을 문자열로 지정해야 합니다.
대소문자를 구분하지 않는 문자열을 일치시키려면 다음을 수행하십시오.
"(?i)"
대/소문자를 구분하지 않는 일치를 시작합니다."(?-i)"
대/소문자를 구분하지 않는 일치를 종료합니다.
예를 들어 표현식 "(?i)a(?-i)cme"
은(는) 다음과 같은 문자열과 일치합니다.
"a"
또는"A"
으로 시작합니다. 대소문자를 구분하지 않는 일치입니다."cme"
로 끝납니다. 대소문자를 구분하는 일치 항목입니다.
이러한 문자열은 표현식과 일치합니다:
"acme"
"Acme"
다음 예시에서는 $regex
연산자를 사용하여 정규 표현식 "(?i)a(?-i)cme"
와(과) 일치하는 name
필드 문자열을 찾습니다.
{ name: { $regex: "(?i)a(?-i)cme" } }
버전 6.1부터, MongoDB는 PCRE2(Perl 호환 정규 표현식) 라이브러리를 사용하여 정규 표현식 패턴 일치를 구현합니다. PCRE 2에 대한 자세한 내용은 PCRE 설명서를 참조하세요.
$regex
개인정보 정책에 $not
$not
연산자는 두 가지 모두에서 논리적 NOT
연산을 수행할 수 있습니다.
정규 표현식 객체(즉,
/pattern/
)예를 들면 다음과 같습니다.
db.inventory.find( { item: { $not: /^p.*/ } } ) $regex
연산자 표현식예를 들면 다음과 같습니다.
db.inventory.find( { item: { $not: { $regex: "^p.*" } } } ) db.inventory.find( { item: { $not: { $regex: /^p.*/ } } } )
인덱스 사용하기
$regex
쿼리의 인덱스 사용 및 성능은 쿼리가 대소문자를 구분하는지 아니면 구분하지 않는지에 따라 달라집니다.
대소문자를 구분하는 쿼리
대소문자를 구분하는 정규 표현식 쿼리의 경우, 필드에 대한 인덱스가 있으면 MongoDB는 인덱스의 값에 대해 정규 표현식을 일치시키므로 컬렉션 스캔보다 빠를 수 있습니다.
정규식이 '접두사 표현식'인 경우, 즉 모든 잠재적 일치 항목이 동일한 문자열로 시작하는 경우 추가적인 최적화가 이루어질 수 있습니다. 이렇게 하면 MongoDB가 해당 접두사에서 '범위'를 구성하고 그 범위 내에 있는 인덱스의 값과만 일치시킬 수 있습니다.
정규식은 캐럿(^
) 또는 왼쪽 앵커(\A
)로 시작하고 그 뒤에 간단한 기호의 문자열이 오는 경우 "접두사 표현식" 입니다. 예를 들어, 정규식 /^abc.*/
은(는) abc
으로 시작하는 인덱스의 값에 대해서만 일치시켜 최적화됩니다.
또한 /^a/
, /^a.*/
및 /^a.*$/
은(는) 동등한 문자열과 일치하지만 성능 특성이 다릅니다. 적절한 인덱스가 존재하는 경우 이러한 모든 표현식은 인덱스를 사용합니다. 그러나 /^a.*/
및 /^a.*$/
은(는) 더 느립니다. /^a/
은(는) 접두사와 일치한 후 검색을 중지할 수 있습니다.
대소문자를 구분하지 않는 쿼리
대소문자를 구분하지 않는 인덱스는 일반적으로 $regex
쿼리에 대한 성능을 향상시키지 않습니다. $regex
구현은 데이터 정렬을 인식하지 못하며 대소문자를 구분하지 않는 인덱스를 효율적으로 사용할 수 없습니다.
예시
이 섹션의 예시에서는 다음의 products
collection을 사용합니다.
db.products.insertMany( [ { _id: 100, sku: "abc123", description: "Single line description." }, { _id: 101, sku: "abc789", description: "First line\nSecond line" }, { _id: 102, sku: "xyz456", description: "Many spaces before line" }, { _id: 103, sku: "xyz789", description: "Multiple\nline description" }, { _id: 104, sku: "Abc789", description: "SKU starts with A" } ] )
LIKE
매치 수행
다음 예시는 sku
필드가 "%789"
과 같은 모든 문서와 일치합니다.
db.products.find( { sku: { $regex: /789$/ } } )
이 예시는 다음의 SQL LIKE 문과 유사합니다.
SELECT * FROM products WHERE sku like "%789";
출력 예시:
[ { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 103, sku: 'xyz789', description: 'Multiple\nline description' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
대소문자를 구분하지 않는 정규식 일치 수행
다음 예시에서는 i
옵션을 사용하여 ABC
로 시작하는 sku
값의 문서에 대해 대소문자를 구분하지 않는 일치를 수행합니다.
db.products.find( { sku: { $regex: /^ABC/i } } )
출력 예시:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
지정된 패턴으로 시작하는 줄에 대한 여러 줄 일치 검색
다음 예시에서는 m
옵션을 사용하여 여러 줄 문자열에 대해 S
문자로 시작하는 줄을 일치시킵니다.
db.products.find( { description: { $regex: /^S/, $options: 'm' } } )
출력 예시:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
m
옵션이 없는 경우 예시 출력은 다음과 같습니다.
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
$regex
패턴에 앵커가 포함되어 있지 않으면 다음의 예와 같이 패턴이 문자열 전체와 일치합니다.
db.products.find( { description: { $regex: /S/ } } )
출력 예시:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
.
점 문자를 사용하여 새 줄과 일치시키기
다음 예시에서는 s
옵션을 사용하여 점 문자(즉, 다음과 같음)를 허용합니다. .
)를 사용하여 새 줄을 포함한 모든 문자를 일치시킬 수 있고, i
옵션을 사용하여 대소문자를 구분하지 않고 일치시킬 수 있습니다.
db.products.find( { description: { $regex: /m.*line/, $options: 'si' } } )
출력 예시:
[ { _id: 102, sku: 'xyz456', description: 'Many spaces before line' }, { _id: 103, sku: 'xyz789', description: 'Multiple\nline description' } ]
s
옵션이 없으면 출력 예시는 다음과 같습니다.
[ { _id: 102, sku: 'xyz456', description: 'Many spaces before line' } ]
패턴에서 공백 무시
다음 예에서는 x
옵션을 사용하여 공백과 일치 패턴에서 #
로 표시되고 \n
로 끝나는 주석을 무시합니다.
var pattern = "abc #category code\n123 #item number" db.products.find( { sku: { $regex: pattern, $options: "x" } } )
출력 예시:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' } ]
정규식을 사용하여 문자열의 대소문자 일치시키기
다음 예시에서는 표현식 "(?i)a(?-i)bc"
을(를) 사용하여 sku
필드 문자열이 포함된 항목과 일치시킵니다:
"abc"
"Abc"
db.products.find( { sku: { $regex: "(?i)a(?-i)bc" } } )
출력 예시:
[ { _id: 100, sku: 'abc123', description: 'Single line description.' }, { _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, { _id: 104, sku: 'Abc789', description: 'SKU starts with A' } ]
정규식 옵션을 확장하여 ASCII 이외의 문자와 일치시키기
버전 6.1에 추가.
기본적으로 특정 정규식 옵션(예: /b
및 /w
)은 ASCII 문자만 인식합니다. 이로 인해 UTF-8 문자에 대해 정규식 일치를 수행할 때 예기치 않은 결과가 발생할 수 있습니다.
MongoDB 6.1부터는 UTF-8 문자와 일치하도록 *UCP
정규식 옵션을 지정할 수 있습니다.
중요
UCP 옵션의 성능
*UCP
은(는) 일치를 수행하기 위해 다단계 테이블 조회가 필요하므로 *UCP
옵션을 사용하면 옵션을 지정하지 않은 경우보다 쿼리 속도가 느려집니다.
예를 들어 songs
collection에 다음 문서가 있다고 가정해 보겠습니다.
db.songs.insertMany( [ { _id: 0, "artist" : "Blue Öyster Cult", "title": "The Reaper" }, { _id: 1, "artist": "Blue Öyster Cult", "title": "Godzilla" }, { _id: 2, "artist" : "Blue Oyster Cult", "title": "Take Me Away" } ] )
다음 정규식 쿼리는 정규식 일치에서 \b
옵션을 사용합니다. \b
옵션은 단어 경계와 일치합니다.
db.songs.find( { artist: { $regex: /\byster/ } } )
출력 예시:
[ { _id: 0, artist: 'Blue Öyster Cult', title: 'The Reaper' }, { _id: 1, artist: 'Blue Öyster Cult', title: 'Godzilla' } ]
반환된 artist
필드의 단어 중 일치하는 문자열(yster
)로 시작하는 단어가 없기 때문에 이전 결과는 예상치 못한 결과입니다. 문서 _id: 0
및 _id: 1
의 Ö
문자는 UTF-8 문자이므로 일치를 수행할 때 무시됩니다.
예상되는 결과는 쿼리가 어떤 문서도 반환하지 않는다는 것입니다.
쿼리에서 UTF-8 문자를 인식할 수 있도록 하려면 패턴 앞에 *UCP
옵션을 지정하십시오.
db.songs.find( { artist: { $regex: "(*UCP)/\byster/" } } )
이전 쿼리에서는 예상된 결과인 어떤 문서도 반환하지 않습니다.
팁
정규식 패턴의 이스케이프 문자
*UCP
또는 다른 정규식 옵션을 지정할 때 셸 또는 드라이버에 올바른 이스케이프 문자를 사용해야 합니다.