Docs Menu

$regexFindAll (aggregation)

$regexFindAll

Provides regular expression (regex) pattern matching capability in aggregation expressions. The operator returns an array of documents that contains information on each match. If a match is not found, returns an empty array.

$regexFindAll演算子の構文は次のとおりです。

{ $regexFindAll: { input: <expression> , regex: <expression>, options: <expression> } }
フィールド
説明

string に 正規表現パターン を適用します。string、または string に変換される有効な式を指定できます。

適用する正規表現パターン。 または正規表現パターン のいずれかに解決される任意の有効な を指定できます。string/<pattern>/正規表現/<pattern>/を使用する場合、正規表現オプションimを指定することもできます(ただし、 sまたはxオプションは含まれません)。

  • "pattern"

  • /<pattern>/

  • /<pattern>/<options>

あるいは、オプションフィールドを使用して正規表現オプションを指定することもできます。sまたはx オプションを指定するには、オプションフィールドを使用する必要があります。

regexoptionsフィールドと フィールドの両方にオプションを指定することはできません。

任意。次の <options> は正規表現で使用できます。

regexoptionsフィールドと フィールドの両方にオプションを指定することはできません。

オプション
説明

i

大文字と小文字の両方で一致するように、大文字と小文字を区別せずに一致します。 オプションは、 optionsフィールドまたは 正規表現 フィールドの一部として指定できます。

m

アンカーを含むパターン(先頭は ^、末尾は $)の場合、複数行の値を含む文字列に対して各行の先頭または末尾で一致します。このオプションを指定しない場合、これらのアンカーは文字列の先頭か末尾で一致します。

パターンにアンカーが含まれていない場合、または文字列値に改行文字が含まれていない場合(\n など)、 m オプションは効果がありません。

x

エスケープされたり、文字クラスに含まれていたりしない限り、 パターン内のすべての空白文字を無視できる「拡張」機能です。

さらに、エスケープされていないハッシュまたはパウンド(#)記号と次の改行を含む間にある文字は無視されるため、複雑なパターンでコメントを含めることができます。これはデータ文字にのみ適用され、パターン内の特殊文字シーケンスに空白文字が表示されることはありません。

x オプションは VT 文字の処理には影響しません(コード 11)。

オプションはoptionsフィールドでのみ指定できます。

s

ドット記号(.)を、改行文字を含むすべての文字と一致します。

オプションはoptionsフィールドでのみ指定できます。

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> }, ... ]

以下も参照してください。

バージョン 6.1 以降、MongoDB では、正規表現パターン マッチングを実装するために PCRE 2(Perl Compatible Regular Expressions、Perl 互換正規表現)ライブラリが使用されます。PCRE2 の詳細については、PCRE ドキュメントを参照してください。

$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オプションを参照してください。

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/ }
}
}
}
])

正規表現パターンは、 fnameCarolColleenとの一致を見つけます。

{ "_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を使用)。 キャプチャ グループの論理orphoneフィールドに適用して、ニューヨーク市のエリアコードで電話番号を検索する次の例を考えてみましょう。 各グループは、ニューヨーク市のエリアコードを表します。

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演算子の動作を示すには、次のドキュメントを含むサンプル コレクション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/ } } } }
])

この操作では、最後のレコードのみがパターンに一致し、返されたidx2である(バイト インデックスを使用している場合は 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" : [ ] } ] }

注意

regexoptionsフィールドと フィールドの両方にオプションを指定することはできません。

大文字と 小文字 を区別しないパターン一致を実行するには、 正規表現 フィールドの一部または オプション フィールドに 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" : [ ] }

注意

regexoptionsフィールドと フィールドの両方にオプションを指定することはできません。

指定されたアンカー(例: ^$ )の各行には、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" : [ ] }

注意

regexoptionsフィールドと フィールドの両方にオプションを指定することはできません。

パターン内のエスケープされていない空白文字とコメント(エスケープされていないハッシュ「# 」文字と次の改行文字によって示される)を無視するには、 オプション フィールドに 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" : [ ] }

注意

regexoptionsフィールドと フィールドの両方にオプションを指定することはできません。

ドット記号( .)が改行文字 を含む すべての文字と一致するようにするには、 オプション フィールドに 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" : [ ] }

次のドキュメントを含む 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 field email to the document. The new field is an array that contains the result of performing the $regexFindAll on the comment 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 the email array elements to the "email.match" value(s). If the current value of email is null, the new value of email 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 reset names 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 の出力動作」を参照してください。