$text(自己管理型配置)
注意
このページでは、自己管理型型(Atlas以外)デプロイメントのテキスト クエリ機能について説明します。 MongoDB Atlasでホストされているデータに対して、 MongoDBは改良された全文クエリ ソリューションである Atlas Search とベクトル検索ソリューションである Atlas ベクトル検索を提供します。
このページでは、自己管理型配置の $text
演算子について説明します。
定義
$text
$text
は テキストインデックスでインデックス付けされたフィールドの内容に対してテキストクエリを実行します。
互換性
次の環境でホストされる配置には $text
を使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
$text
式の構文は次のとおりです。
{ $text: { $search: <string>, $language: <string>, $caseSensitive: <boolean>, $diacriticSensitive: <boolean> } }
$text
演算子は、次のフィールドを含むテキスト クエリ ドキュメントを受け入れます。
フィールド | タイプ | 説明 |
---|---|---|
$search | string | |
$language | string | 任意。 クエリのストップワードのリストと、ステマーとトークナイザのルールを決定する言語。 指定されていない場合、MongoDB はインデックスのデフォルト言語を使用します。 サポートされている言語については、「自己管理型配置のテキスト検索言語 」を参照してください。
|
$caseSensitive | ブール値 | 任意。大文字・小文字の区別を有効または無効にするブール値のフラグ。デフォルトは 詳細については「大文字と小文字を区別する」を参照してください。 |
$diacriticSensitive | ブール値 | 任意。バージョン 3 のテキスト インデックスに対する発音区別記号の区別を有効または無効にするブール値のフラグ。デフォルトの値は 過去のバージョンのテキスト インデックスに対するテキスト クエリでは、本質的に発音区別符号が区別され、区別なしでの検索はできません。そのため 詳細については「発音区別符号を区別しない」を参照してください。 |
$text
演算子は、デフォルトでは、結果のスコアでソートされた結果を返すことはありません。結果のスコアによる並べ替えの詳細については、テキスト スコアのドキュメントを参照してください。
動作
制限事項
クエリで指定できるのは、最大でも 1 つの
$text
式だけです。$text
は$nor
式には使用できません。$text
は$elemMatch
クエリ式や$elemMatch
プロジェクション式には使用できません。クエリに
$text
式が含まれている場合、hint()
を使用してクエリに使用するインデックスを指定することはできません。クエリに
$text
式が含まれている場合は、$natural
の並べ替え順序は指定できません。特殊なテキストインデックスを必要とする
$text
式と、別のタイプの特殊インデックスを必要とするクエリ 演算子を組み合わせることはできません。たとえば、$text
式を$near
演算子と組み合わせることはできません。ビューは
$text
をサポートしていません。$text
Stable API V 1を使用したインデックスの作成はサポートされていません。
集計で $text
演算子を使う場合、以下の制限も適用されます。
$search
フィールド
$search
フィールドに、 $text
演算子が解析し、テキスト インデックスをクエリするために使用する単語の string を指定します。
$text
演算子は、string 内のほとんどの句読点を区切り文字として扱います。ただし、タームを除外するハイフン マイナス(-
)や、フレーズを指定するエスケープされた二重引用符 \"
は除きます。
注意
$text
式の $search
フィールドは $search 集計ステージとは異なります。このステージはAtlas Search が提供するものです。$search
集計ステージは指定されたフィールドに対して全文検索を実行するもので、MongoDB Atlas でのみ使用できます。
フレーズ
個々の用語ではなく、フレーズを照合するには、次のようにフレーズをエスケープされた二重引用符(\"
)で囲みます。
"\"ssl certificate\""
$text
操作の $search
文字列にフレーズと個々のタームが含まれている場合、$text
はそのフレーズを含むドキュメントのみと一致します。
例えば $search
文字列が渡された場合は次のようになります。
"\"ssl certificate\" authority key"
$text
演算子は、"ssl
certificate"
というフレーズを含むドキュメントを返します。
注意
$text
演算子は複数のフレーズでは使えません。
除外
単語の前にハイフンマイナス ( -
) を付けると、その単語は除外されます。
単語を除外すると、除外対象の単語を含めたドキュメントを検索結果から除外します。
否定の単語のみを含む文字列が渡された場合、
$text
はどのドキュメントとも一致しません。pre-market
のようなハイフン付きの単語は除外タームではありません。ハイフン付きの単語で使用した場合、$text
演算子はハイフン マイナス(-
)を区切り文字として扱います。このインスタンスでmarket
という単語を除外するには、pre
と-market
の間にスペースを含め、たとえばpre -market
とします。
$text
演算子は論理 AND
演算子を使用して、操作にすべての否定を追加します。
一致操作
ストップワード
$text
演算子は、英語のthe
やand
などの言語固有のストップワードを無視します。
語幹付き単語
大文字と小文字を区別せず、発音区別符号による区別がない設定にすると、$text
演算子は発音区別符号のある単語全体を照合します。ドキュメントフィールドに blueberry
という単語が含まれている場合、$search
タームが blue
の $text
操作は一致しません。ただし、blueberry
または blueberries
は一致します。
大文字と小文字の区別と語幹のある単語
大文字と小文字の区別を使用する場合($caseSensitive: true
)、接尾辞の語幹に大文字が含まれている場合、 $text
演算子は正確な単語と一致します。
発音区別符号の区別と語幹のある単語
発音区別符号の区別 ($diacriticSensitive: true
) を使用する場合、接尾辞の語幹に発音区別符号が含まれていると、 $text
演算子は正確な単語と一致します。
大文字と小文字の区別なし
$text
演算子は、デフォルトではテキストインデックスの大文字と小文字を区別しない設定になります。
バージョン 3 のテキスト インデックスでは、発音区別符号の有無にかかわらず、ラテン文字や、キリル文字など非ラテン文字では大文字と小文字が区別されません。詳細については、テキスト インデックスを参照してください。
text
インデックスの過去のバージョンでは、発音区別符号のないラテン文字、つまり[A-z]
では大文字と小文字が区別されません。
$caseSensitive
オプション
text
インデックスが大文字と小文字を区別しない場合に大文字と小文字の区別をサポートするには、$caseSensitive: true
を指定します。
大文字と小文字の区別プロセス
$caseSensitive: true
であり、text
インデックスで大文字と小文字が区別されない場合、$text
演算子は次のようになります。
最初に
text
インデックスのクエリで、大文字と小文字が区別されないか、発音区別符号による区別がないか調べます。そして指定されたタームの大文字と小文字が一致するドキュメントのみを返すように、
$text
操作には、一致しないドキュメントをフィルタリングで除外する追加のステージが含まれています。
$caseSensitive: true
で接尾辞の語幹に大文字が含まれている場合、$text
演算子は正確な単語と一致します。
$caseSensitive: true
を指定するとパフォーマンスに影響する可能性があります。
発音区別符号の区別なし
$text
演算子はデフォルトでテキストインデックスの発音区別符号を区別しません。
バージョン 3 のテキスト インデックスでは、発音区別符号は区別されません。つまりインデックスでは、
é
、ê
、e
など、発音区別符号を含む文字と含まない文字を区別しません。text
インデックスの以前のバージョンでは、発音区別記号が区別されます。
$diacriticSensitive
オプション
text
インデックスで発音区別符号の区別をサポートするには、 $diacriticSensitive: true
を指定します。
text
インデックスの以前のバージョンに対するテキストクエリは、本質的に発音区別符号が区別され、これを区別しないということはできません。そのため、$text
演算子の $diacriticSensitive
オプションは、以前のバージョンの text
インデックスでは効果がありません。
発音区別符号を区別するプロセス
text
インデックスのバージョン 3 で発音区別符号を区別する ($diacriticSensitive: true
) を使用するのが、$text
演算子です。
まず、発音区別符号を区別しない
text
インデックスをクエリします。そして指定されたタームの発音区別符号が付いた文字と一致するドキュメントのみを返すために、
$text
操作には、一致しないドキュメントをフィルタリングで除外する追加のステージが含まれています。
$diacriticSensitive: true
を指定するとパフォーマンスに影響する可能性があります。
$diacriticSensitive: true
を以前のバージョンの text
インデックスで使用すると、$text
演算子は発音区別符号を区別する text
インデックスをクエリします。
$diacriticSensitive: true
であり、接尾辞の語幹に発音区別符号が含まれている場合、 $text
演算子は正確な単語と一致します。
テキストスコア
$text
演算子は各結果ドキュメントにスコアを割り当てます。スコアは、特定のクエリに対するドキュメントの関連性を表します。スコアは、sort()
メソッド仕様の一部だけでなく、プロジェクション式の一部にもなります。{ $meta: "textScore" }
式には $text
操作の処理に関する情報が含まれます。プロジェクションまたはソートのためのスコアへのアクセス方法の詳細については、$meta
プロジェクション 演算子を参照してください。
例
次の例では、フィールド subject
にバージョン 3 のテキストインデックスを持つコレクション articles
を想定しています。
db.articles.createIndex( { subject: "text" } )
コレクションに次のドキュメントを入力します。
db.articles.insertMany( [ { _id: 1, subject: "coffee", author: "xyz", views: 50 }, { _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, { _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, { _id: 4, subject: "baking", author: "xyz", views: 100 }, { _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, { _id: 6, subject: "Сырники", author: "jkl", views: 80 }, { _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, { _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } ] )
$text
1 つの単語で
次の例では、coffee
の $search
文字列を指定しています。
db.articles.find( { $text: { $search: "coffee" } } )
この操作は、インデックスされた subject
フィールドに coffee
というタームを含むドキュメント、より正確に言うと語幹のあるバージョンの単語を返します。
{ _id: 1, subject: 'coffee', author: 'xyz', views: 50 }, { _id: 7, subject: 'coffee and cream', author: 'efg', views: 10 }, { _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 }
$search
タームのいずれかに一致する
$search
文字列がスペースで区切られた文字列の場合、$text
は各タームに対して論理 OR
操作を実行し、いずれかのタームを含むドキュメントを返します。
次の例では、スペースで区切られた 3 つのタームの $search
文字列と "bake coffee cake"
を指定します。
db.articles.find( { $text: { $search: "bake coffee cake" } } )
この操作は、インデックスされた subject
フィールドにbake
または coffee
または cake
のいずれかを含むドキュメント、より正確に言うと語幹のあるバージョンの単語を返します。
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 } { "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 } { "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 } { "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90 } { "_id" : 4, "subject" : "baking", "author" : "xyz", "views" : 100 }
$text
1 つのフレーズで
完全に一致するフレーズを 1 つのタームとして一致させるには、引用符をエスケープします。
次の例えでは coffee shop
というフレーズに一致します。
db.articles.find( { $text: { $search: "\"coffee shop\"" } } )
この操作は coffee shop
というフレーズを含むドキュメントを返します。
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
次の例えでは、 coffee shop
と Cafe
con Leche
というフレーズが一致しています。これは 2 つのフレーズの論理和です。
db.articles.find( { $text: { $search: "\'coffee shop\' \'Cafe con Leche\'" } } )
この操作では、両方のフレーズを含むドキュメント(両方のフレーズのタームを含むドキュメントを含む)が返されます。
[ { _id: 8, subject: 'Cafe con Leche', author: 'xyz', views: 10 }, { _id: 5, subject: 'Café Con Leche', author: 'abc', views: 200 }, { _id: 1, subject: 'coffee', author: 'xyz', views: 50 }, { _id: 7, subject: 'coffee and cream', author: 'efg', views: 10 }, { _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 } ]
タームを含むドキュメントを除外する
否定タームはマイナス記号 -
が前に付いたタームです。タームを否定すると、$text
演算子はそのタームを含むドキュメントを結果から除外します。
次の例えは coffee
という単語を含むが shop
というタームは含まないドキュメント、より正確に言うと語幹のあるバージョンの単語を検索します。
db.articles.find( { $text: { $search: "coffee -shop" } } )
この操作により、次のドキュメントが返されます。
{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 } { "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 }
異なる言語のクエリ
任意である $text
式の $language
フィールドを使用して、ストップワードのリストと、$search
文字列のステマーとトークナイザのルールを決定する言語を指定します。
none
の値に default_language
を指定すると、テキストインデックスはストップワードを含むフィールド内の各単語を解析し、接尾辞の語幹を無視します。
次の例えでは es
を指定します。すなわち、トークン化、ステミング、ストップワードを決定する言語としてのスペイン語です。
db.articles.find( { $text: { $search: "leche", $language: "es" } } )
この例えでは次のドキュメントが返されます。
{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 } { "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz", "views" : 10 }
$text
式は、言語名spanish
も受け入れることができます。 サポートされている言語については、「自己管理型配置でのテキスト検索言語」を参照してください。
大文字と小文字、発音区別符号を区別しない
$text
演算子は、 text
インデックスの大文字と小文字を区別せず、発音区別符号も区別しないことを前提としています。 バージョン3 text
インデックスは、発音区別符号を区別せず、大文字と小文字の不区別を拡大して、キリル文字と発音区別符号付き文字を含めます。 詳細については、「テキストインデックスの大文字と小文字を区別しない 」および「 テキストインデックスを発音区別符号を区別しない 」を参照してください。
次の例えでは сы́рники
または CAFÉS
というタームに対して、大文字と小文字を区別せず、発音区別符号も区別しないテキストクエリを実行します。
db.articles.find( { $text: { $search: "сы́рники CAFÉS" } } )
text
インデックスのバージョン 3 を使用すると、オペレーションは次のドキュメントと一致します。
{ "_id" : 6, "subject" : "Сырники", "author" : "jkl", "views" : 80 } { "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 } { "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz", "views" : 10 }
以前のバージョンの text
インデックスでは、クエリはどのドキュメントにも一致しませんでした。
大文字と小文字の区別
大文字と小文字の区別を有効にするには $caseSensitive: true
を指定します。$caseSensitive: true
を指定するとパフォーマンスに影響する可能性があります。
タームによる大文字と小文字の区別
次の例えでは、Coffee
というタームに対して大文字と小文字を区別したクエリを実行します。
db.articles.find( { $text: { $search: "Coffee", $caseSensitive: true } } )
この操作は次のドキュメントとのみ一致します。
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
フレーズによる大文字と小文字の区別
次の例えでは、 Café Con Leche
というフレーズに対して大文字と小文字を区別したクエリを実行します。
db.articles.find( { $text: { $search: "\"Café Con Leche\"", $caseSensitive: true } } )
この操作は次のドキュメントとのみ一致します。
{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 }
除外するタームの大文字と小文字の区別
否定タームはマイナス記号-
が先頭に付いたタームです。 タームを除外すると、 $text
演算子は結果からそのタームを含むドキュメントを除外します。 除外するタームの大文字と小文字の区別を指定することもできます。
次の例えでは、Coffee
という単語を含み小文字のターム shop
は含まない、より正確に言うと語幹のあるバージョンのドキュメントに対して、大文字と小文字を区別するクエリを実行します。
db.articles.find( { $text: { $search: "Coffee -shop", $caseSensitive: true } } )
この操作は次のドキュメントと一致します。
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg" }
発音区別符号の区別
バージョン 3 のテキストインデックスで発音区別符号の区別を有効にするには、$diacriticSensitive: true
を指定します。$diacriticSensitive: true
を指定するとパフォーマンスに影響する可能性があります。
タームによる発音区別符号の区別
次の例えでは CAFÉ
というターム、より正確には語幹のあるバージョンの単語に対して、発音区別符号を区別するテキストクエリを実行します。
db.articles.find( { $text: { $search: "CAFÉ", $diacriticSensitive: true } } )
この操作は次のドキュメントにのみ一致します。
{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc" }
除外するタームの発音区別符号の区別
$diacriticSensitive
オプションは、除外するタームにも適用されます。除外するタームとは、マイナス記号 -
を先頭に持つタームのことです。タームを除外すると、$text
演算子は結果からそのタームを含むドキュメントを除外します。
次の例えでは、leches
というタームを含むが cafés
というターム、より正確に言うと語幹のあるバージョンの単語は含まない文書に対して、発音区別符号を区別するテキストクエリを実行します。
db.articles.find( { $text: { $search: "leches -cafés", $diacriticSensitive: true } } )
この操作は次のドキュメントと一致します。
{ "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz" }
関連性スコアの例え
関連性スコアを返す
次の例では、cake
というタームのテキスト クエリを実行し、プロジェクション ドキュメントの $meta
演算子を使用して、一致する各ドキュメントに関連性スコアを追加します。
db.articles.find( { $text: { $search: "cake" } }, { score: { $meta: "textScore" } } )
返されるドキュメントには、ドキュメントの関連性スコアを含む追加フィールド score
が含まれています。
{ "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90, "score" : 0.75 }
関連性スコアによる並べ替え
{ $meta: "textScore" }
プロジェクションで式を指定せずに、 でsort()
式を指定できます。例:db.articles.find( { $text: { $search: "cake" } } ).sort( { score: { $meta: "textScore" } } ) 最終的に
textScore
を投影することなく、結果となるドキュメントを関連性で並べ替えることができます。{ $meta: "textScore" }
式を投影とsort()
の両方に含めると、投影ドキュメントとソート ドキュメントで式のフィールド名が異なる場合があります。For example, in the following operation, the projection uses a field namedscore
for the expression and thesort()
uses the field namedignoredName
.db.articles.find( { $text: { $search: "cake" } } , { score: { $meta: "textScore" } } ).sort( { ignoredName: { $meta: "textScore" } } )
一致するドキュメントの上位 2 件を返す
一致する上位 n
件のドキュメントを返すには、limit()
メソッドを sort()
と組み合わせて使用します。
次の例えでは、coffee
というタームをクエリし、結果をスコアの降順でソートし、一致するドキュメントの上位 2 つに結果を限定しています。
db.articles.find( { $text: { $search: "coffee" } }, { score: { $meta: "textScore" } } ).sort( { score: { $meta: "textScore" } } ).limit(2)
追加のクエリ式とソート式を使用した $text
次の例えは author
が "xyz"
と等しく、インデックスされたフィールド subject
に coffee
または bake
というタームが含まれるドキュメントと一致します。この操作では date
の昇順、その後に関連性スコアの降順というソート順序も指定されています。
db.articles.find( { author: "xyz", $text: { $search: "coffee bake" } }, { score: { $meta: "textScore" } } ).sort( { date: 1, score: { $meta: "textScore" } } )