$regexFindAll (aggregation)
定義
構文
$regexFindAll
演算子の構文は次のとおりです。
{ $regexFindAll: { input: <expression> , regex: <expression>, options: <expression> } }
フィールド | 説明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
string に 正規表現パターン を適用します。string、または string に変換される有効な式を指定できます。 | |||||||||||
適用する正規表現パターン。 または正規表現パターン のいずれかに解決される任意の有効な 式 を指定できます。string
あるいは、オプションフィールドを使用して正規表現オプションを指定することもできます。
| |||||||||||
任意。次の
|
戻り値
The operator returns an array:
If the operator does not find a match, the operator returns an empty array.
If the operator finds a match, the operator returns an array of documents that contains the following information for each match:
the matching string in the 入力,
the code point index (not byte index) of the matching string in the 入力, and
An array of the strings that corresponds to the groups captured by the matching string. Capturing groups are specified with unescaped parenthesis
()
in the regex pattern.
[ { "match" : <string>, "idx" : <num>, "captures" : <array of strings> }, ... ]
以下も参照してください。
動作
PCRE ライブラリ
バージョン 6.1 以降、MongoDB では、正規表現パターン マッチングを実装するために PCRE 2(Perl Compatible Regular Expressions、Perl 互換正規表現)ライブラリが使用されます。PCRE2 の詳細については、PCRE ドキュメントを参照してください。
$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" } ])
次の操作では、 コレクションの照合順序を使用して、大文字と小文字を区別せず、発音区別符号も区別しない一致が実行されます。
db.myColl.aggregate( [ { $match: { category: "cafe" } } ] )
この操作では、次の 3 つのドキュメントが返されます。
{ "_id" : 1, "category" : "café" } { "_id" : 2, "category" : "cafe" } { "_id" : 3, "category" : "cafE" }
However, the aggregation expression $regexFind
ignores
collation; that is, the following regular expression pattern matching examples
are case-sensitive and diacritic sensitive:
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
出力動作
If your regex pattern contains capture
groups and the pattern finds a match in the
入力, the captures
array in the results
corresponds to the groups captured by the matching string. Capture
groups are specified with unescaped parentheses ()
in the
regex pattern. The length of the
captures
array equals the number of capture groups in the pattern
and the order of the array matches the order in which the capture groups
appear.
下記のドキュメントを含む、contacts
という名前のサンプル コレクションを作成します。
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" } ])
次のパイプラインは、正規表現パターン/(C(ar)*)ol/
をfname
フィールドに適用します。
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
配列内の要素は、2 つのキャプチャ グループに対応します。 一致するドキュメントがグループによってキャプチャされない場合(例: Colleen
とグループ(ar)
の場合)、 $regexFindAll
はグループを null プレースホルダーに置き換えます。
前の例に示すように、 captures
配列には各キャプチャ グループの要素が含まれています(非キャプチャにはnull
を使用)。 キャプチャ グループの論理or
をphone
フィールドに適用して、ニューヨーク市のエリアコードで電話番号を検索する次の例を考えてみましょう。 各グループは、ニューヨーク市のエリアコードを表します。
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 オプションを含めます。
// 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" } }
For example, the following aggregation performs a case-insensitive $regexFindAll
on the description
field. 正規表現パターン/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
フィールドと フィールドの両方にオプションを指定することはできません。
指定されたアンカー(例: ^
、$
)の各行には、string 正規表現 フィールドの一部または オプション フィールドに m オプションを含め 。
// 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" } }
次の例には、複数行の文字列に対して文字i
m
または で始まる行を検索するために、s
オプションとS
オプションの両方が含まれています。
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
フィールドと フィールドの両方にオプションを指定することはできません。
ドット記号( .
)が改行文字 を含む すべての文字と一致するようにするには、 オプション フィールドに 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
を使用して string からのメールを解析します
次のドキュメントを含む 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" } ])
The following aggregation uses the $regexFindAll
to extract
all emails from the comment
field (case insensitive).
db.feedback.aggregate( [ { $addFields: { "email": { $regexFindAll: { input: "$comment", regex: /[a-z0-9_.+-]+@[a-z0-9_.+-]+\.[a-z0-9_.+-]+/i } } } }, { $set: { email: "$email.match"} } ] )
- 第 1 ステージ
The stage uses the
$addFields
stage to add a new fieldemail
to the document. The new field is an array that contains the result of performing the$regexFindAll
on thecomment
field:{ "_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" : [ ] } ] } - 第 2 ステージ
The stage use the
$set
stage to reset theemail
array elements to the"email.match"
value(s). If the current value ofemail
is null, the new value ofemail
is set to 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" ] }
キャプチャされたグループを使用してユーザー名を解析します
次のドキュメントを含む 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" } ])
To reply to the feedback, assume you want to parse the local-part of
the email address to use as the name in the greetings. Using the
captured
field returned in the $regexFindAll
results,
you can parse out the local part of each email address:
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" ] } } } } } ] )
- 第 1 ステージ
このステージでは、
$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" ] } ] } - 第 2 ステージ
The stage use the
$set
stage with the$reduce
operator to resetnames
to an array that contains the"$names.captures"
elements.{ "_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" ] }
以下も参照してください。
captures
配列の動作とその他の例については、「captures
の出力動作」を参照してください。