

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 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 相容功能：
+ 在單一欄位上建立文字索引。
+ 建立包含多個文字欄位的複合文字索引。
+ 執行單字或多字搜尋。
+ 使用權重控制搜尋結果。
+ 依分數排序搜尋結果。
+ 在彙總管道中使用文字索引。
+ 搜尋確切的片語。

## 使用 Amazon DocumentDB 文字索引
<a name="using-text-search"></a>

若要在包含字串資料的欄位上建立文字索引，請指定字串「文字」，如下所示：

單一欄位索引：

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

此索引支援指定集合中「註解」字串欄位中的文字搜尋查詢。

在多個字串欄位上建立複合文字索引：

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

此索引支援指定集合中「註解」和「標題」字串欄位中的文字搜尋查詢。建立複合文字索引時，您最多可以指定 30 個欄位。建立後，您的文字搜尋查詢將查詢所有索引欄位。

**注意**  
每個集合只允許一個文字索引。

### 在 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"}}]})
```

輸出：

上述命令會傳回具有文字索引欄位的文件，其中包含任何形式的「興趣」和等於 5 的「star\$1rating」。此命令的輸出看起來像這樣：

```
{ "_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)
```

輸出：

上述命令會傳回滿足篩選條件的一個結果：

```
{ "_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` 、`aggregate`、`count`、 和 `delete`命令`$search`也支援 `findAndModify``update`和 。

### 彙總運算子
<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>

您可以在複合文字索引中將權重指派給最多三個欄位。指派給文字索引中欄位的預設權重為一 (1)。權重是選用參數，範圍必須介於 1 到 100000 之間。

```
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 文字索引不區分大小寫。
+ 文字索引僅支援英文。
+ 不支援陣列 （或多重索引鍵） 欄位的文字索引。例如，使用文件 \$1「a」：【「apple」、「pie」】\$1 在「a」上建立文字索引將會失敗。
+ 不支援萬用字元文字索引。
+ 不支援唯一文字索引。
+ 不支援排除字詞。

## 最佳實務和指導方針
<a name="text-search-best-practice"></a>
+ 為了在涉及依文字分數排序的文字搜尋查詢上獲得最佳效能，我們建議您在載入資料之前建立文字索引。
+ 文字索引需要額外的儲存體，才能最佳化索引資料的內部複本。這會產生額外的成本影響。

## 文字索引 V2
<a name="text-index-v2"></a>

Amazon DocumentDB 8.0 推出新版本的文字索引 (V2)，可變更基礎文字搜尋剖析器，以提供更多與 MongoDB 的相容性。

除了 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 中具有下列限制：
+ 文字索引存放 lexemes 及其位置資訊。在單一文件中，所有 lexemes 及其位置資訊的合併大小限制為 1MB。