쿼리로 시작하는 MongoDB
이 MongoDB 기사에서 사용자는 $regex
를 사용하여 쿼리를 시작하는 방법을 배웁니다. 쿼리의 패턴 일치 문자열에 대한 정규식 기능을 제공합니다.
MongoDB는 $regex
를 사용하는 쿼리로 시작합니다.
$regex
를 사용하려면 다음 구문 중 하나를 사용하십시오.
{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } }
MongoDB에서 사용자는 정규식 객체(즉, /pattern/
)를 사용하여 정규식을 지정할 수도 있습니다.
{ <field>: /pattern/<options> }
사용자는 다음 <옵션>
과 함께 정규식을 사용할 수 있습니다.
옵션 | 설명 | 구문 제한 |
---|---|---|
i |
대문자와 소문자를 일치시키기 위해 대소문자를 구분하지 않습니다. | |
m |
여러 줄 값이 있는 문자열의 경우 시작 부분에 ^ 및 끝 부분에 $ 와 같은 앵커를 포함하는 패턴에 대해 각 줄의 시작 또는 끝에서 일치합니다. 패턴에 앵커가 없거나 문자열 값에 개행 문자(예: \n )가 포함되어 있지 않으면 m 옵션은 효과가 없습니다. |
|
x |
$regex 패턴의 모든 공백 문자는 이스케이프되거나 문자 클래스에 포함되지 않는 한 무시됩니다. 또한 중간에 있는 문자를 무시하고 이스케이프 처리되지 않은 해시/파운드(# ) 문자와 다음 줄 바꿈을 포함하여 복잡한 패턴으로 주석을 추가할 수 있습니다. 공백 문자는 패턴의 특수 문자 시퀀스 내에 나타나지 않을 수 있습니다. 이것은 데이터 문자에만 해당됩니다. x 옵션은 VT 문자가 처리되는 방식(즉, 코드 11)에 영향을 주지 않습니다. |
$options 구문을 사용하는 $regex 가 필요합니다. |
s |
점 문자(. )가 새 줄을 포함하여 모든 문자와 일치하도록 허용합니다. |
$options 구문이 포함된 $regex 가 필요합니다. |
$regex
연산자는 전역 검색 수정자 g
를 지원하지 않습니다.
$in
식
JavaScript 정규식 객체(예: /pattern/
)만 $in
쿼리 식에 정규식을 통합하는 데 사용할 수 있습니다. 다음 예를 고려하십시오.
{ 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
가 있는 $regex
연산자
사용자는 x
또는 s
옵션을 사용하려면 $options
연산자와 함께 $regex
연산자를 사용해야 합니다. 예를 들어 i
및 s
옵션을 지정하려면 $options
를 사용해야 합니다.
{ name: { $regex: /acme.*corp/, $options: "si" } }
{ name: { $regex: 'acme.*corp', $options: "si" } }
PCRE 대 자바스크립트
사용자는 JavaScript에서 지원되지 않는 정규식 패턴의 PCRE 지원 기능을 활용하기 위해 문자열로 패턴과 함께 $regex
연산자 표현식을 사용해야 합니다.
예를 들어 패턴에서 (?i)
및 (?-i)
를 사용하여 나머지 패턴에 대소문자를 구분하지 않으려면 $regex
연산자를 문자열로 패턴과 함께 사용해야 합니다.
{ name: { $regex: '(?i)a(?-i)cme' } }
$regex
및 $not
버전 4.0.7부터 $not
연산자는 다음 둘 모두에서 논리적인 NOT
작업을 수행할 수 있습니다.
-
정규식 객체(예:
/pattern/
)예를 들어:
db.inventory.find( { item: { $not: /^p.*/ } } )
-
$regex
연산자 표현식(MongoDB 4.0.7부터).예를 들어:
db.inventory.find( { item: { $not: { $regex: "^p.*" } } } )
db.inventory.find( { item: { $not: { $regex: /^p.*/ } } } )
버전 4.0.6 및 이전 버전에서는 $not
연산자를 정규식 개체(예: /pattern/
)와 함께 사용할 수 있지만 $regex
연산자 식에는 사용할 수 없습니다.
필드에 인덱스가 있는 경우 MongoDB는 인덱스의 값에 대해 정규식을 확인합니다. 이는 대/소문자를 구분하는 정규식 쿼리에 대한 컬렉션 스캔보다 빠를 수 있습니다.
정규 표현식에 모든 잠재적 일치 항목이 정확한 문자열로 시작함을 나타내는 접두어 표현식이 있는 경우 더 많은 최적화가 가능합니다. 이를 통해 MongoDB는 접두사에서 범위를 만들고 해당 범위 내의 인덱스 값과만 일치시킬 수 있습니다.
정규 표현식이 캐럿(^
) 또는 왼쪽 앵커(\A
)로 시작하고 뒤에 단순 기호 문자열이 오는 경우 이를 접두사 표현식이라고 합니다. 예를 들어 정규식 /^abc.*/
는 abc
로 시작하는 인덱스 값에 대해서만 일치시켜 최적화됩니다.
또한 /^a/
, /^a.*/
및 /^a.*$/
는 모두 유사한 문자열과 일치하지만 성능은 다릅니다.
적합한 색인이 있으면 이러한 모든 표현식에서 이를 사용합니다. 그럼에도 불구하고 /^a.*/
및 /^a.*$/
는 더 느립니다. 접두사를 일치시킨 후 /^a/
는 검색을 중지할 수 있습니다.
대소문자를 구분하지 않는 정규식 쿼리는 인덱스를 효율적으로 활용할 수 없습니다. 예를 들어 $regex
구현은 데이터 정렬을 인식하지 않으므로 대소문자를 구분하지 않는 인덱스를 사용할 수 없습니다.
예:
다음 예에서는 다음 문서와 함께 products
라는 컬렉션을 사용합니다.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." },
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" },
{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before line" },
{ "_id" : 103, "ski" : "xyz789", "description" : "Multiple\nline description" }
LIKE
문
이 예제는 스키
필드가 "%789"
와 같은 모든 문서와 일치합니다.
db.products.find( { ski: { $regex: /789$/ } } )
예는 다음 SQL LIKE
문과 유사합니다.
SELECT * FROM products
WHERE ski like "%789";
대소문자를 구분하지 않는 정규식 일치
다음 예에서는 i
옵션을 사용하고 ski
값이 ABC
로 시작하는 문서에 대해 대소문자를 구분하지 않는 일치를 수행합니다.
db.products.find( { ski: { $regex: /^ABC/i } } )
쿼리는 다음 문서와 일치합니다.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }
여러 줄 일치
m
옵션은 다음 예에서 여러 줄 문자열에서 문자 S
로 시작하는 줄을 일치시키는 데 사용됩니다.
db.products.find( { description: { $regex: /^S/, $options: 'm' } } )
쿼리는 아래 제공된 다음 문서와 일치합니다.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }
m
옵션이 없으면 쿼리는 다음 문서와만 일치합니다.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
$regex
패턴에 앵커가 포함되어 있지 않으면 다음 예제와 같이 패턴이 전체 문자열에 적용됩니다.
db.products.find( { description: { $regex: /S/ } } )
그러면 $regex
가 두 문서와 일치합니다.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }
.
새 줄과 일치하는 도트 문자
s
옵션을 사용하면 점 문자(.
)가 새 줄을 포함한 모든 문자와 일치하고 i
옵션을 사용하면 대소문자를 구분하지 않고 일치시킬 수 있습니다.
db.products.find( { description: { $regex: /m.*line/, $options: 'si' } } )
쿼리는 다음 문서와 일치합니다.
{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "ski" : "xyz789", "description" : "Multiple\nline description" }
쿼리는 s
옵션이 없는 다음 문서와만 일치합니다.
{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before line" }
패턴의 공백
일치 패턴에서 x
옵션은 #
으로 표시된 공백과 주석을 무시하고 n:.
으로 끝납니다.
var pattern = "abc #category code\n123 #item number"
db.products.find( { ski: { $regex: pattern, $options: "x" } } )
쿼리는 다음 문서와 일치합니다.
{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }