$regexFindAll(集計)
定義
構文
$regexFindAll
演算子の構文は次のとおりです。
{ $regexFindAll: { input: <expression> , regex: <expression>, options: <expression> } }
フィールド | 説明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
適用する正規表現パターン。 または正規表現パターン のいずれかに解決される任意の有効な 式 を指定できます。string
あるいは、オプションフィールドを使用して正規表現オプションを指定することもできます。
| |||||||||||
任意。次の
|
戻り値
この演算子は、次のように配列を返します。
動作
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" }
ただし、集計式$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
配列は、一致する string によってキャプチャされたグループに対応します。 キャプチャ グループは、正規表現パターンで、エスケープされていない括弧()
を使用して指定されています。 captures
配列の長さは、パターン内のキャプチャ グループの数と等しく、配列の順序はキャプチャ グループが表示される順序と一致します。
下記のドキュメントを含む、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" } ])
次の集計では、 $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"} } ] )
- 第 1 ステージ
このステージでは、
$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" : [ ] } ] } - 第 2 ステージ
このステージは
$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" ] }
キャプチャされたグループを使用してユーザー名を解析します
次のドキュメントを含む 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" ] } } } } } ] )
- 第 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 ステージ
このステージは、
$set
演算子とともに$reduce
names
ステージを使用して、"$names.captures"
を 要素を含む配列にリセットします。{ "_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" ] }