

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Amazon DocumentDB でのテキスト検索の実行
<a name="text-search"></a>

Amazon DocumentDB のネイティブフルテキスト検索機能 (テキストインデックス v1) を使用すると、特殊目的のテキストインデックスを使用して、大きなテキストデータセットに対してテキスト検索を実行できます。このセクションでは、テキストインデックス機能の機能について説明し、Amazon DocumentDB でテキストインデックスを作成および使用する手順について説明します。テキスト検索における制限事項もリストアップします。

**Topics**
+ [サポートされている機能](#text-search-capabilities)
+ [Amazon DocumentDB テキストインデックスの使用](#using-text-search)
+ [MongoDB との違い](#text-index-mongo-diff)
+ [ベストプラクティスとガイドライン](#text-search-best-practice)
+ [テキストインデックス V2](#text-index-v2)
+ [制限事項](#text-search-limitations)

## サポートされている機能
<a name="text-search-capabilities"></a>

Amazon DocumentDB テキスト検索は、以下の MongoDB API 互換機能をサポートしています。
+ 1 つのフィールドにテキストインデックスを作成します。
+ 複数のテキストフィールドを含む複合テキストインデックスを作成します。
+ 単一単語または複数単語の検索を実行します。
+ 重み付けにより検索結果を制御します。
+ 検索結果をスコア順にソートします。
+ 集約パイプラインでテキストインデックスを使用します。
+ 完全一致フレーズを検索できます。

## Amazon DocumentDB テキストインデックスの使用
<a name="using-text-search"></a>

文字列データを含むフィールドにテキストインデックスを作成するには、次のように文字列「text」を指定します。

単一フィールドインデックス

```
db.test.createIndex({"comments": "text"})
```

このインデックスは、指定されたコレクションの「comments」文字列フィールドのテキスト検索クエリをサポートします。

複数の文字列フィールドに複合テキストインデックスを作成します。

```
db.test.createIndex({"comments": "text", "title":"text"})
```

このインデックスは、指定されたコレクションの「comments」および「title」文字列フィールドでのテキスト検索クエリをサポートします。複合テキストインデックスを作成する際は、最大 30 個のフィールドを指定できます。作成したテキスト検索クエリは、すべてのインデックス付きフィールドを対象にクエリを実行します。

**注記**  
各コレクションで許可されるテキストインデックスは 1 つだけです。

### Amazon DocumentDB コレクションでのテキストインデックスの一覧表示
<a name="w2aac47c27b9c19"></a>

以下の例に示すように、コレクションで `getIndexes()` を使用して、テキストインデックスを含むインデックスを特定して記述できます。

```
rs0:PRIMARY> db.test.getIndexes()
[
   {
      "v" : 4,
      "key" : {
         "_id" : 1
      },
      "name" : "_id_",
      "ns" : "test.test"
   },
   {
      "v" : 1,
      "key" : {
         "_fts" : "text",
         "_ftsx" : 1
      },
      "name" : "contents_text",
      "ns" : "test.test",
      "default_language" : "english",
      "weights" : {
         "comments" : 1
      },
      "textIndexVersion" : 1
   }
]
```

インデックスを作成したら、Amazon DocumentDB コレクションへのデータの挿入をスタートできます。

```
db.test.insertMany([{"_id": 1, "star_rating": 4, "comments": "apple is red"},
                    {"_id": 2, "star_rating": 5, "comments": "pie is delicious"},
                    {"_id": 3, "star_rating": 3, "comments": "apples, oranges - healthy fruit"},
                    {"_id": 4, "star_rating": 2, "comments": "bake the apple pie in the oven"},
                    {"_id": 5, "star_rating": 5, "comments": "interesting couch"},
                    {"_id": 6, "star_rating": 5, "comments": "interested in couch for sale, year 2022"}])
```

### テキスト検索クエリの実行
<a name="w2aac47c27b9c21"></a>

**単一語テキスト検索クエリを実行する**

テキスト検索を実行するには、`$text` と `$search` 演算子を使用する必要があります。次の例では、テキストインデックス付きフィールドに文字列「apple」または、「apple」を他の形式で含む(「apples」、等)文字列を含むすべてのドキュメントを返します。

```
db.test.find({$text: {$search: "apple"}})
```

出力:

このコマンドの出力は次のようになります。

```
{ "_id" : 1, "star_rating" : 4, "comments" : "apple is red" }
{ "_id" : 3, "star_rating" : 3, "comments" : "apples, oranges - healthy fruit" }
{ "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven" }
```

**複数単語のテキスト検索を実行する**

Amazon DocumentDB データに対して複数単語のテキスト検索を実行することもできます。次のコマンドは、「apple」または「pie」を含むテキストインデックス付きフィールドを持つドキュメントを返します。

```
db.test.find({$text: {$search: "apple pie"}})
```

出力:

このコマンドの出力は次のようになります。

```
{ "_id" : 1, "star_rating" : 4, "comments" : "apple is red" }
{ "_id" : 2, "star_rating" : 5, "comments" : "pie is delicious" }
{ "_id" : 3, "star_rating" : 3, "comments" : "apples, oranges - healthy fruit" }
{ "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven" }
```

**複数単語のフレーズテキスト検索を実行する**

複数単語のフレーズ検索には、次の例を使用します。

```
db.test.find({$text: {$search: "\"apple pie\""}})
```

出力:

上記のコマンドは、「apple pie」というフレーズに完全一致する文字列を含むテキストインデックス付きフィールドを持つドキュメントを返します。このコマンドの出力は次のようになります。

```
{ "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven" }
```

**フィルターを使用してテキスト検索を実行する**

テキスト検索を他のクエリ演算子と組み合わせて、追加の基準に基づいて結果をフィルタリングすることもできます。

```
db.test.find({$and: [{star_rating: 5}, {$text: {$search: "interest"}}]})
```

出力:

上記のコマンドは、「interest」のすべての変化形と、「星評価」が 5 であるテキストインデックス付きフィールドを持つドキュメントを返します。このコマンドの出力は次のようになります。

```
{ "_id" : 5, "star_rating" : 5, "comments" : "interesting couch" }
{ "_id" : 6, "star_rating" : 5, "comments" : "interested in couch for sale, year 2022" }
```

**テキスト検索で返されるドキュメントの数を制限する**

`limit` を使用して、返されるドキュメントの数を制限できます。

```
db.test.find({$and: [{star_rating: 5}, {$text: {$search: "couch"}}]}).limit(1)
```

出力:

上記のコマンドは、フィルターを満たす 1 つの結果を返します。

```
{ "_id" : 5, "star_rating" : 5, "comments" : "interesting couch" }
```

**テキストスコアで結果をソートする**

次の例では、テキスト検索結果をテキストスコアでソートします。

```
db.test.find({$text: {$search: "apple"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}})
```

出力:

上記のコマンドは、文字列「apple」または、「apple」を他の形式で含む(「apples」、等)文字列含むテキストインデックス付きフィールドを持つドキュメントを返し、それぞれのドキュメントの検索用語との関連性の高さに基づいて結果をソートします。このコマンドの出力は次のようになります。

```
{ "_id" : 1, "star_rating" : 4, "comments" : "apple is red", "score" : 0.6079270860936958 }
{ "_id" : 3, "star_rating" : 3, "comments" : "apples, oranges - healthy fruit", "score" : 0.6079270860936958 }
{ "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven", "score" : 0.6079270860936958 }
```

`$text` および `$search` は、`aggregate`、`count`、`findAndModify`、`update`、`delete` の各コマンドでもサポートされています。

### 集約演算子
<a name="w2aac47c27b9c23"></a>

**`$match` を使用した集約パイプライン**

```
db.test.aggregate(
   [{ $match: { $text: { $search: "apple pie" } } }]
)
```

出力:

このコマンドでは次のようなレスポンスが返されます。

```
{ "_id" : 1, "star_rating" : 4, "comments" : "apple is red" }
{ "_id" : 3, "star_rating" : 3, "comments" : "apple - a healthy fruit" }
{ "_id" : 4, "star_rating" : 2, "comments" : "bake the apple pie in the oven" }
{ "_id" : 2, "star_rating" : 5, "comments" : "pie is delicious" }
```

**他の集約演算子の組み合わせ**

```
db.test.aggregate(
   [
      { $match: { $text: { $search: "apple pie" } } },
      { $sort: { score: { $meta: "textScore" } } },
      { $project: { score: { $meta: "textScore" } } }
   ]
)
```

出力:

このコマンドでは次のようなレスポンスが返されます。

```
{ "_id" : 4, "score" : 0.6079270860936958 }
{ "_id" : 1, "score" : 0.3039635430468479 }
{ "_id" : 2, "score" : 0.3039635430468479 }
{ "_id" : 3, "score" : 0.3039635430468479 }
```

### テキストインデックスを作成するときに複数のフィールドを指定する
<a name="w2aac47c27b9c25"></a>

重み付けは、複合テキストインデックスの最大 3 つのフィールドに付与することができます。テキストインデックスの各フィールドに割り当てられたデフォルトの重み値は 1 です。重み付けはオプションのパラメータであり、1～100,000 の範囲である必要があります。

```
db.test.createIndex(
   {
     "firstname": "text",
     "lastname": "text",
     ...
   },
   {
     weights: {
       "firstname": 5,
       "lastname":10,
       ...
     },
     name: "name_text_index"
   }
 )
```

## MongoDB との違い
<a name="text-index-mongo-diff"></a>

Amazon DocumentDB のテキストインデックス機能は、用語-頻出度アルゴリズムによる転置インデックスを使用します。デフォルトでは、テキストインデックスはスパースです。解析ロジック、トークン化区切り文字などが異なるため、同じデータセットまたはクエリ形状に対して MongoDB と同じ結果セットが返されない場合があります。

Amazon DocumentDB テキストインデックスと MongoDB には、他にも以下のような違いがあります。
+ テキスト以外のインデックスを用いた複合インデックスはサポートされていません。
+ Amazon DocumentDB テキストインデックスは大文字と小文字を区別しません。
+ テキストインデックスでは、英語のみがサポートされています。
+ 配列 (またはマルチキー) フィールドのテキストインデックス構成はサポートされていません。例えば、文字 a のテキストインデックスとして、\$1“a”:[“apple”, “pie”]\$1 などといったドキュメントを使用したインデックスを作成しようとすると失敗します。
+ ワイルドカードのテキストインデックス構成はサポートされていません。
+ 一意のテキストインデックスはサポートされていません。
+ 用語の除外はサポートされていません。

## ベストプラクティスとガイドライン
<a name="text-search-best-practice"></a>
+ テキストスコアによるソートを含むテキスト検索クエリのパフォーマンスを最適化するには、データをロードする前に実際にテキストインデックスを作成してみることをお勧めします。
+ テキストインデックスの運用には、インデックス化されたデータの最適化された内部コピーを保持するために追加のストレージが必要となります。これには、追加のコストが伴います。

## テキストインデックス V2
<a name="text-index-v2"></a>

Amazon DocumentDB 8.0 では、MongoDB との互換性を高めるために基盤となるテキスト検索パーサーを変更する新しいバージョンのテキストインデックス (V2) が導入されました。

V1 テキストインデックスが提供する機能に加えて、V2 テキストインデックスは次のサポートも提供します。
+ プランナーは、可能な場合はパイプラインの早い段階で \$1match ステージを移動し、後続のステージで処理されるドキュメントの数を減らします。

  ```
  rs0:PRIMARY> db.coll.createIndex({ "a": "text" });
  rs0:PRIMARY> db.coll.find()
  { "_id" : 1, "a" : "jane.doe_1234@company.com" }
  { "_id" : 2, "a" : "janedoe@company.com" }
  { "_id" : 3, "a" : "/home/user/company/thesis.pdf" }
  { "_id" : 4, "a" : "/home/user/path/jane.pdf" }
  { "_id" : 5, "a" : "http://www.company.com/path" }
  { "_id" : 6, "a" : "https://company.com/path/../home" }
  
  //Sample queries
  rs0:PRIMARY> db.coll.find({ $text: { $search: "jane" } });
  rs0:PRIMARY> db.coll.find({ $text: { $search: "doe_1234" } });
  rs0:PRIMARY> db.coll.find({ $text: { $search: "http" } });
  
  // Text Index V1 results
  None
  
  // Text Index V2 results
  { "_id" : 1, "a" : "jane.doe_1234@company.com" }
  { "_id" : 4, "a" : "/home/user/path/jane.pdf" }
  { "_id" : 5, "a" : "http://www.company.com/path" }
  ```

## 制限事項
<a name="text-search-limitations"></a>

テキスト検索は Amazon DocumentDB で次の制限があります。
+ テキストインデックスは、レキシームとその位置情報を保存します。1 つのドキュメント内のすべてのレキシームとその位置情報の合計サイズは 1MB に制限されています。