쿼리로 시작하는 MongoDB

Tahseen Tauseef 2023년6월20일
  1. MongoDB는 $regex를 사용하는 쿼리로 시작합니다.
  2. . 새 줄과 일치하는 도트 문자
쿼리로 시작하는 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' ] } }

xs가 있는 $regex 연산자

사용자는 x 또는 s 옵션을 사용하려면 $options 연산자와 함께 $regex 연산자를 사용해야 합니다. 예를 들어 is 옵션을 지정하려면 $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 작업을 수행할 수 있습니다.

  1. 정규식 객체(예: /pattern/)

    예를 들어:

db.inventory.find( { item: { $not: /^p.*/ } } )
  1. $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." }