정규식 찾기(집계)
정의
구문
$regexFindAll
연산자의 구문은 다음과 같습니다.
{ $regexFindAll: { input: <expression> , regex: <expression>, options: <expression> } }
필드 | 설명 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
선택 사항입니다. 다음 참고
|
반환
연산자는 다음과 같이 배열을 반환합니다.
연산자가 일치하는 항목을 찾지 못하면 연산자는 빈 배열을 반환합니다.
연산자가 일치하는 항목을 찾으면 연산자는 각 일치 항목에 대해 다음 정보가 포함된 문서 배열을 반환합니다.
input에서 일치하는 string,
코드 포인트 입력 에서 일치하는 의 string 인덱스(바이트 인덱스가 아님)입니다.
일치하는 문자열로 캡처된 그룹에 해당하는 문자열 배열입니다. 캡처 그룹은 정규식 패턴에서 이스케이프되지 않은 괄호
()
로 지정됩니다.
[ { "match" : <string>, "idx" : <num>, "captures" : <array of strings> }, ... ]
행동
$regexFindAll
및 데이터 정렬
$regexFindAll
는 컬렉션에 지정된 데이터 정렬인 db.collection.aggregate()
및 인덱스(사용된 경우)를 무시합니다.
예를 들어 데이터 정렬 강도가 1
인 샘플 컬렉션을 생성합니다(예: 기본 문자만 비교하고 대소문자 및 발음 구별 부호와 같은 다른 차이점은 무시합니다).
db.createCollection( "myColl", { collation: { locale: "fr", strength: 1 } } )
다음 문서를 삽입합니다.
db.myColl.insertMany([ { _id: 1, category: "café" }, { _id: 2, category: "cafe" }, { _id: 3, category: "cafE" } ])
collection의 데이터 정렬을 사용하여 다음 작업은 대/소문자를 구분하지 않고 발음 구별 기호를 구분하지 않는 일치를 수행합니다.
db.myColl.aggregate( [ { $match: { category: "cafe" } } ] )
이 작업은 다음 3개의 문서를 반환합니다.
{ "_id" : 1, "category" : "café" } { "_id" : 2, "category" : "cafe" } { "_id" : 3, "category" : "cafE" }
그러나 애그리게이션 표현식 $regexFind
는 데이터 정렬을 무시합니다. 즉, 다음 정규 표현식 패턴 일치 예제는 대소문자를 구분하고 발음 부호를 구분합니다.
db.myColl.aggregate( [ { $addFields: { results: { $regexFindAll: { input: "$category", regex: /cafe/ } } } } ] ) db.myColl.aggregate( [ { $addFields: { results: { $regexFindAll: { input: "$category", regex: /cafe/ } } } } ], { collation: { locale: "fr", strength: 1 } } // Ignored in the $regexFindAll )
두 연산 모두 다음과 같은 결과를 반환합니다.
{ "_id" : 1, "category" : "café", "results" : [ ] } { "_id" : 2, "category" : "cafe", "results" : [ { "match" : "cafe", "idx" : 0, "captures" : [ ] } ] } { "_id" : 3, "category" : "cafE", "results" : [ ] }
대소문자를 구분하지 않는 정규식 패턴 일치를 수행하려면 i
옵션을 대신 사용하세요. i
옵션을 예시로 참조하세요.
captures
출력 동작
정규식 패턴에 캡처 그룹이 포함되어 있고 패턴이 입력 에서 일치하는 항목을 찾는 경우 결과의 captures
배열은 일치하는 문자열로 캡처된 그룹에 해당합니다. 캡처 그룹은 정규식 패턴에서 이스케이프되지 않은 괄호 ()
로 지정됩니다. captures
배열의 길이는 패턴의 캡처 그룹 수와 같고 배열의 순서는 캡처 그룹이 나타나는 순서와 일치합니다.
다음 문서를 사용하여 contacts
라는 이름의 샘플 collection을 생성합니다.
db.contacts.insertMany([ { "_id": 1, "fname": "Carol", "lname": "Smith", "phone": "718-555-0113" }, { "_id": 2, "fname": "Daryl", "lname": "Doe", "phone": "212-555-8832" }, { "_id": 3, "fname": "Polly", "lname": "Andrews", "phone": "208-555-1932" }, { "_id": 4, "fname": "Colleen", "lname": "Duncan", "phone": "775-555-0187" }, { "_id": 5, "fname": "Luna", "lname": "Clarke", "phone": "917-555-4414" } ])
다음 파이프라인은 fname
필드에 정규식 패턴 /(C(ar)*)ol/
을 다음과 같이 적용합니다.
db.contacts.aggregate([ { $project: { returnObject: { $regexFindAll: { input: "$fname", regex: /(C(ar)*)ol/ } } } } ])
정규식 패턴은 fname
값 Carol
및 Colleen
과 일치하는 항목을 찾습니다.
{ "_id" : 1, "returnObject" : [ { "match" : "Carol", "idx" : 0, "captures" : [ "Car", "ar" ] } ] } { "_id" : 2, "returnObject" : [ ] } { "_id" : 3, "returnObject" : [ ] } { "_id" : 4, "returnObject" : [ { "match" : "Col", "idx" : 0, "captures" : [ "C", null ] } ] } { "_id" : 5, "returnObject" : [ ] }
패턴에 중첩된 그룹 (ar)
이 포함된 캡처 그룹 (C(ar)*)
이 포함되어 있습니다. captures
배열의 요소는 두 개의 캡처 그룹에 해당합니다. 일치하는 문서가 그룹에 의해 캡처되지 않은 경우(예: Colleen
및 그룹 (ar)
), $regexFindAll
는 그룹을 null 자리 표시자로 바꿉니다.
이전 예제에 표시된 것처럼 captures
배열에는 각 캡처 그룹에 대한 요소가 포함되어 있습니다(비캡처에는 null
사용). 다음 예제에서 phone
필드에 논리적 or
의 캡처 그룹을 적용하여 뉴욕시 지역 번호가 있는 전화번호를 검색하는 경우를 살펴보세요. 각 그룹은 뉴욕시 지역 번호를 나타냅니다.
db.contacts.aggregate([ { $project: { nycContacts: { $regexFindAll: { input: "$phone", regex: /^(718).*|^(212).*|^(917).*/ } } } } ])
정규식 패턴과 일치하는 문서의 경우 captures
배열은 일치하는 캡처 그룹을 포함하고 캡처하지 않는 그룹을 null
로 바꿉니다.
{ "_id" : 1, "nycContacts" : [ { "match" : "718-555-0113", "idx" : 0, "captures" : [ "718", null, null ] } ] } { "_id" : 2, "nycContacts" : [ { "match" : "212-555-8832", "idx" : 0, "captures" : [ null, "212", null ] } ] } { "_id" : 3, "nycContacts" : [ ] } { "_id" : 4, "nycContacts" : [ ] } { "_id" : 5, "nycContacts" : [ { "match" : "917-555-4414", "idx" : 0, "captures" : [ null, null, "917" ] } ] }
예제
$regexFindAll
및 해당 옵션
이 예시에서 말한 $regexFindAll
연산자의 동작을 설명하기 위해 다음 문서를 사용하여 샘플 컬렉션 products
를 만듭니다.
db.products.insertMany([ { _id: 1, description: "Single LINE description." }, { _id: 2, description: "First lines\nsecond line" }, { _id: 3, description: "Many spaces before line" }, { _id: 4, description: "Multiple\nline descriptions" }, { _id: 5, description: "anchors, links and hyperlinks" }, { _id: 6, description: "métier work vocation" } ])
기본적으로 $regexFindAll
는 대/소문자 구분 일치를 수행합니다. 예를 들어, 다음 집계는 description
필드에서 대소문자를 구분하는 $regexFindAll
를 수행합니다. 정규식 패턴 /line/
은 다음과 같이 그룹화를 지정하지 않습니다.
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /line/ } } } } ])
이 연산은 다음을 반환합니다:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "line", "idx" : 6, "captures" : [ ]}, { "match" : "line", "idx" : 19, "captures" : [ ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "line", "idx" : 23, "captures" : [ ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "line", "idx" : 9, "captures" : [ ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
다음 정규식 패턴 /lin(e|k)/
은 패턴에서 그룹화 (e|k)
을 지정합니다.
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /lin(e|k)/ } } } } ])
이 연산은 다음을 반환합니다:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject": [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "line", "idx" : 6, "captures" : [ "e" ] }, { "match" : "line", "idx" : 19, "captures" : [ "e" ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "line", "idx" : 23, "captures" : [ "e" ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "line", "idx" : 9, "captures" : [ "e" ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ { "match" : "link", "idx" : 9, "captures" : [ "k" ] }, { "match" : "link", "idx" : 24, "captures" : [ "k" ] } ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
반환 옵션에서 필드는 idx
코드 포인트입니다 . 즉, 바이트 인덱스가 아닌 인덱스입니다. 예를 들어, 정규식 패턴 을 사용하는 다음 예제를 /tier/
살펴보겠습니다.
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /tier/ } } } } ])
이 연산은 마지막 레코드만 패턴과 일치하고 반환된 idx
가 2
(바이트 인덱스를 사용하는 경우 3 대신)인 경우 다음을 반환합니다.
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ { "match" : "tier", "idx" : 2, "captures" : [ ] } ] }
i
옵션
참고
regex
및 options
필드 모두에 옵션을 지정할 수 없습니다.
대소문자를 구분하지 않는 패턴 일치를 수행하려면 i 옵션을 regex 필드의 일부로 포함하거나 options 필드에 포함합니다.
// Specify i as part of the regex field { $regexFindAll: { input: "$description", regex: /line/i } } // Specify i in the options field { $regexFindAll: { input: "$description", regex: /line/, options: "i" } } { $regexFindAll: { input: "$description", regex: "line", options: "i" } }
예를 들어, 다음 집계는 description
필드에서 대소문자를 구분하지 않는 $regexFindAll
를 수행합니다. 정규식 패턴 /line/
은 다음과 같이 그룹화를 지정하지 않습니다.
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /line/i } } } } ])
이 작업은 다음 문서를 반환합니다.
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ { "match" : "LINE", "idx" : 7, "captures" : [ ] } ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "line", "idx" : 6, "captures" : [ ] }, { "match" : "line", "idx" : 19, "captures" : [ ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "line", "idx" : 23, "captures" : [ ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "line", "idx" : 9, "captures" : [ ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
m
옵션
참고
regex
및 options
필드 모두에 옵션을 지정할 수 없습니다.
지정된 앵커와 일치시키려면(예: ^
, $
) 여러 줄 문자열의 각 줄에 대해 m 옵션을 regex 필드의 일부로 포함하거나 options 필드에 포함해야 합니다.
// Specify m as part of the regex field { $regexFindAll: { input: "$description", regex: /line/m } } // Specify m in the options field { $regexFindAll: { input: "$description", regex: /line/, options: "m" } } { $regexFindAll: { input: "$description", regex: "line", options: "m" } }
다음 예제에는 여러 줄 문자열의 경우 문자 s
또는 S
로 시작하는 줄을 일치시키는 i
및 m
옵션이 모두 포함되어 있습니다.
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /^s/im } } } } ])
이 연산은 다음을 반환합니다:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ { "match" : "S", "idx" : 0, "captures" : [ ] } ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "s", "idx" : 12, "captures" : [ ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
x
옵션
참고
regex
및 options
필드 모두에 옵션을 지정할 수 없습니다.
패턴에서 이스케이프되지 않은 모든 공백 문자와 주석(이스케이프되지 않은 해시 #
문자와 다음 줄 바꿈 문자로 표시됨)을 무시하려면 옵션 필드에 s 옵션을 포함합니다.
// Specify x in the options field { $regexFindAll: { input: "$description", regex: /line/, options: "x" } } { $regexFindAll: { input: "$description", regex: "line", options: "x" } }
다음 예제에는 이스케이프되지 않은 공백과 주석을 건너뛰는 x
옵션이 포함되어 있습니다.
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex: /lin(e|k) # matches line or link/, options:"x" } } } } ])
이 연산은 다음을 반환합니다:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ { "match" : "line", "idx" : 6, "captures" : [ "e" ] }, { "match" : "line", "idx" : 19, "captures" : [ "e" ] } ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "line", "idx" : 23, "captures" : [ "e" ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "line", "idx" : 9, "captures" : [ "e" ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ { "match" : "link", "idx" : 9, "captures" : [ "k" ] }, { "match" : "link", "idx" : 24, "captures" : [ "k" ] } ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
s
옵션
참고
regex
및 options
필드 모두에 옵션을 지정할 수 없습니다.
패턴의 점 문자(예: .
)가 새 줄 문자를 포함한 모든 문자와 일치하도록 하려면 options 필드에 s 옵션을 포함합니다.
// Specify s in the options field { $regexFindAll: { input: "$description", regex: /m.*line/, options: "s" } } { $regexFindAll: { input: "$description", regex: "m.*line", options: "s" } }
다음 예에는 점 문자(예:.)가 새 줄을 포함한 모든 문자와 일치하도록 허용하는 s
옵션과 대소문자를 구분하지 않는 일치를 수행하는 i
옵션이 포함되어 있습니다.
db.products.aggregate([ { $addFields: { returnObject: { $regexFindAll: { input: "$description", regex:/m.*line/, options: "si" } } } } ])
이 연산은 다음을 반환합니다:
{ "_id" : 1, "description" : "Single LINE description.", "returnObject" : [ ] } { "_id" : 2, "description" : "First lines\nsecond line", "returnObject" : [ ] } { "_id" : 3, "description" : "Many spaces before line", "returnObject" : [ { "match" : "Many spaces before line", "idx" : 0, "captures" : [ ] } ] } { "_id" : 4, "description" : "Multiple\nline descriptions", "returnObject" : [ { "match" : "Multiple\nline", "idx" : 0, "captures" : [ ] } ] } { "_id" : 5, "description" : "anchors, links and hyperlinks", "returnObject" : [ ] } { "_id" : 6, "description" : "métier work vocation", "returnObject" : [ ] }
를 $regexFindAll
사용하여 문자열에서 이메일 구문 분석
다음 문서를 사용하여 샘플 collection feedback
을 만듭니다.
db.feedback.insertMany([ { "_id" : 1, comment: "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com" }, { "_id" : 2, comment: "I wanted to concatenate a string" }, { "_id" : 3, comment: "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com" }, { "_id" : 4, comment: "It's just me. I'm testing. fred@MongoDB.com" } ])
다음 애그리게이션에서는 $regexFindAll
를 사용하여 comment
필드에서 모든 이메일을 추출합니다(대소문자 구분 없음).
db.feedback.aggregate( [ { $addFields: { "email": { $regexFindAll: { input: "$comment", regex: /[a-z0-9_.+-]+@[a-z0-9_.+-]+\.[a-z0-9_.+-]+/i } } } }, { $set: { email: "$email.match"} } ] )
- 첫 번째 단계
이 단계에서는
$addFields
단계를 사용하여 문서에 새 필드email
을 추가합니다. 새 필드는comment
필드에$regexFindAll
을 수행한 결과를 포함하는 배열입니다.{ "_id" : 1, "comment" : "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com", "email" : [ { "match" : "aunt.arc.tica@example.com", "idx" : 38, "captures" : [ ] } ] } { "_id" : 2, "comment" : "I wanted to concatenate a string", "email" : [ ] } { "_id" : 3, "comment" : "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com", "email" : [ { "match" : "cam@mongodb.com", "idx" : 56, "captures" : [ ] }, { "match" : "c.dia@mongodb.com", "idx" : 75, "captures" : [ ] } ] } { "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "email" : [ { "match" : "fred@MongoDB.com", "idx" : 28, "captures" : [ ] } ] } - 두 번째 단계
이 단계에서는
$set
단계를 사용하여email
배열 요소를"email.match"
값으로 재설정합니다.email
의 현재 값이 null이면email
의 새로운 값도 null로 설정됩니다.{ "_id" : 1, "comment" : "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com", "email" : [ "aunt.arc.tica@example.com" ] } { "_id" : 2, "comment" : "I wanted to concatenate a string", "email" : [ ] } { "_id" : 3, "comment" : "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com", "email" : [ "cam@mongodb.com", "c.dia@mongodb.com" ] } { "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "email" : [ "fred@MongoDB.com" ] }
캡처한 그룹을 사용하여 사용자 이름 구문 분석
다음 문서를 사용하여 샘플 collection feedback
을 만듭니다.
db.feedback.insertMany([ { "_id" : 1, comment: "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com" }, { "_id" : 2, comment: "I wanted to concatenate a string" }, { "_id" : 3, comment: "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com" }, { "_id" : 4, comment: "It's just me. I'm testing. fred@MongoDB.com" } ])
피드백에 회신하기 위해 인사말에 이름으로 사용할 이메일 주소의 로컬 부분을 구문 분석한다고 가정해 보겠습니다. $regexFindAll
결과에서 반환된 captured
필드를 사용해 각 이메일 주소의 로컬 부분을 구문 분석할 수 있습니다.
db.feedback.aggregate( [ { $addFields: { "names": { $regexFindAll: { input: "$comment", regex: /([a-z0-9_.+-]+)@[a-z0-9_.+-]+\.[a-z0-9_.+-]+/i } }, } }, { $set: { names: { $reduce: { input: "$names.captures", initialValue: [ ], in: { $concatArrays: [ "$$value", "$$this" ] } } } } } ] )
- 첫 번째 단계
이 단계에서는
$addFields
단계를 사용하여 문서에 새 필드names
을 추가합니다. 새 필드는comment
필드에$regexFindAll
를 수행한 결과를 포함합니다.{ "_id" : 1, "comment" : "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com", "names" : [ { "match" : "aunt.arc.tica@example.com", "idx" : 38, "captures" : [ "aunt.arc.tica" ] } ] } { "_id" : 2, "comment" : "I wanted to concatenate a string", "names" : [ ] } { "_id" : 3, "comment" : "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com", "names" : [ { "match" : "cam@mongodb.com", "idx" : 56, "captures" : [ "cam" ] }, { "match" : "c.dia@mongodb.com", "idx" : 75, "captures" : [ "c.dia" ] } ] } { "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "names" : [ { "match" : "fred@MongoDB.com", "idx" : 28, "captures" : [ "fred" ] } ] } - 두 번째 단계
이 단계에서는
$set
단계를$reduce
연산자와 함께 사용하여"$names.captures"
요소를 포함하는 배열로names
을(를) 재설정합니다.{ "_id" : 1, "comment" : "Hi, I'm just reading about MongoDB -- aunt.arc.tica@example.com", "names" : [ "aunt.arc.tica" ] } { "_id" : 2, "comment" : "I wanted to concatenate a string", "names" : [ ] } { "_id" : 3, "comment" : "How do I convert a date to string? Contact me at either cam@mongodb.com or c.dia@mongodb.com", "names" : [ "cam", "c.dia" ] } { "_id" : 4, "comment" : "It's just me. I'm testing. fred@MongoDB.com", "names" : [ "fred" ] }