MongoDBでは、$indexOfBytes
集約パイプライン演算子は、文字列でサブストリングのオカレンスを検索し、最初にオカレンスのUTF-8バイトインデックスを返します。
UTFバイトインデックスはゼロベースです(つまり、0
で始まります 。
構文
構文は次のようになります:
{ $indexOfBytes: [ <string expression>, <substring expression>, <start>, <end> ] }
場所:
<string expression>
検索する文字列です。<substring expression>
文字列内で検索するサブ文字列です。-
<start>
検索の開始インデックス位置を指定するオプションの引数です。非負の整数に解決される任意の有効な式にすることができます。 -
<end>
検索の終了インデックス位置を指定するオプションの引数です。非負の整数に解決される任意の有効な式にすることができます。
指定された値が見つからない場合は、$indexOfBytes
-1
を返します 。
指定された値のインスタンスが複数ある場合は、最初のインスタンスのみが返されます。
例
test
というコレクションがあるとします。 次のドキュメントを使用:
{ "_id" : 1, "data" : "c 2021" } { "_id" : 2, "data" : "© 2021" } { "_id" : 3, "data" : "ไม้เมือง" }
$indexOfBytes
を適用する例を次に示します。 それらのドキュメントへ:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "2021" ] }
}
}
]
)
結果:
{ "data" : "c 2021", "result" : 2 } { "data" : "© 2021", "result" : 3 } { "data" : "ไม้เมือง", "result" : -1 }
サブストリングが各ドキュメントで同じ位置にあるように見えても、最初の2つのドキュメントは異なる結果を生成したことがわかります。最初のドキュメントでは、サブストリングがバイトインデックス位置2
で見つかりました 、2番目のドキュメントは3
にありました 。
この理由は、著作権記号(©
)2番目のドキュメントでは2バイトを使用します。 c
(最初のドキュメントの)文字は1バイトのみを使用します。スペース文字も1バイトを使用します。
$indexOfBytes
の結果 ゼロベースです(インデックスは0
から始まります )、したがって、結果は2
になります。 および3
それぞれ。
3番目のドキュメントについては、部分文字列がまったく見つからなかったため、結果は-1
になります。 。
別の例を次に示します。ただし、今回はタイ語の文字を検索します。
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "เ" ] }
}
}
]
)
結果:
{ "data" : "c 2021", "result" : -1 } { "data" : "© 2021", "result" : -1 } { "data" : "ไม้เมือง", "result" : 9 }
この場合、3番目のドキュメントの3番目の位置に表示される文字を検索すると、そのUTF-8バイトインデックスは9
として返されます。 。
これは、この場合、各文字が3バイトを使用するためです。ただし、2番目の文字には発音区別符号があります。これも3バイトです。したがって、最初の2文字(発音区別符号を含む)は9バイトを使用します。ゼロベースのインデックス付けを考えると、UTF-8バイトインデックスの範囲は0
です。 8
へ 。これは、3番目の文字が9
の位置から始まることを意味します 。
MongoDB $strLenBytes
を参照してください この特定の文字列の各文字のバイト数を返す例の場合。
開始位置を指定
3番目の引数を指定して、検索の開始インデックス位置を指定できます。
次のドキュメントがあるとします。
{ "_id" : 4, "data" : "ABC XYZ ABC" }
$indexOfBytes
を適用する例を次に示します。 開始位置:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "ABC", 1 ] }
}
}
]
)
結果:
{ "data" : "ABC XYZ ABC", "result" : 8 }
この場合、部分文字列の2番目のインスタンスが返されました。これは、1
の位置から検索を開始したためです。 、および部分文字列の最初のインスタンスは、位置0
から始まります。 (検索の開始位置の前)
開始位置が文字列のバイト長より大きいか、終了位置より大きい数値の場合、$indexOfBytes
-1
を返します 。
負の数の場合は、$indexOfBytes
エラーを返します。
終了位置を指定
4番目の引数を指定して、検索の終了インデックス位置を指定することもできます。
この引数を指定する場合は、開始位置も指定する必要があります。そうしないと、この議論が出発点として解釈されることになります。
例:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ", 0, 5 ] }
}
}
]
)
結果:
{ "data" : "ABC XYZ ABC", "result" : -1 }
結果は-1
です これは、部分文字列が見つからなかったことを意味します。これは、0
の位置から検索を開始したためです。 5
の位置で終了しました 、したがって、部分文字列をキャプチャしません。
インデックスの終了位置をインクリメントすると、次のようになります。
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ", 0, 7 ] }
}
}
]
)
結果:
{ "data" : "ABC XYZ ABC", "result" : 4 }
今回は値が含まれ、そのインデックス位置が返されました。
終了位置が開始位置よりも小さい数値の場合、$indexOfBytes
-1
を返します 。
負の数の場合は、$indexOfBytes
エラーを返します。
欠落しているフィールド
フィールドがドキュメントにない場合は、$indexOfBytes
null
を返します 。
次のドキュメントがあるとします。
{ "_id" : 5 }
$indexOfBytes
を適用すると次のようになります :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
結果:
{ "result" : null }
ヌル値
最初の引数がnull
の場合 、$indexOfBytes
null
を返します 。
次のドキュメントがあるとします。
{ "_id" : 6, "data" : null }
$indexOfBytes
を適用すると次のようになります :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
結果:
{ "data" : null, "result" : null }
ただし、2番目の引数(つまり、部分文字列)がnull
の場合 、エラーが返されます:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", null ] }
}
}
]
)
結果:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$indexOfBytes requires a string as the second argument, found: null", "code" : 40092, "codeName" : "Location40092" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:639:17 [email protected]/mongo/shell/assert.js:729:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1058:12 @(shell):1:1
間違ったデータ型
最初の引数が間違ったデータ型である場合(つまり、文字列に解決されない場合)、$indexOfBytes
エラーを返します。
次のドキュメントがあるとします。
{ "_id" : 7, "data" : 123 }
$indexOfBytes
を適用すると次のようになります そのドキュメントへ:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
結果:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$indexOfBytes requires a string as the first argument, found: double", "code" : 40091, "codeName" : "Location40091" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:639:17 [email protected]/mongo/shell/assert.js:729:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1058:12 @(shell):1:1
エラーメッセージに示されているように、$indexOfBytes requires a string as the first argument
。