

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

# Amazon Neptune での文字列以外の OpenSearch インデックス作成
<a name="full-text-search-non-string-indexing"></a>

Amazon Neptune での文字列以外の OpenSearch インデックス作成により、ストリームポーラーを使用して述語の非文字列値を OpenSearch へレプリケートできます。対応する OpenSearch マッピングまたはデータ型に安全に変換できるすべての述語値が OpenSearch へレプリケートされます。

新しいスタックで非文字列インデックスを有効にするには、CloudFormation テンプレート内の `Enable Non-String Indexing` フラグを `true` に設定する必要があります。これはデフォルトの設定です。非文字列インデックスをサポートするように既存のスタックを更新するには、以下の [既存のスタックの更新する](full-text-search-non-string-indexing-update.md) を参照してください。

**注記**  
以前のエンジンバージョンでは、非文字列インデックス作成を有効にしないことをおすすめします。。**`1.0.4.2`**
文字列値を含むものもあれば、文字列以外の値を含むフィールド名を含むクエリもある、複数のフィールドに一致するフィールド名に正規表現を使用する OpenSearch クエリはエラーになります。Neptune のフルテキスト検索クエリがその型の場合にも同じことが起こります。
文字列以外のフィールドでソートする場合は、文字列フィールドと区別するために「.value」をフィールド名に追加する必要があります。

**Contents**
+ [既存の Neptune フルテキスト検索スタックを更新して、非文字列インデックスをサポートする](full-text-search-non-string-indexing-update.md)
+ [Neptune 全文検索でインデックス付けされるフィールドのフィルタリング](full-text-search-non-string-indexing-filters.md)
  + [プロパティまたは述語名でフィルタリングする](full-text-search-non-string-indexing-filters.md#full-text-search-non-string-indexing-filters-name)
  + [プロパティまたは述語値型でフィルタリングする](full-text-search-non-string-indexing-filters.md#full-text-search-non-string-indexing-filters-datatype)
+ [SPARQL および Gremlin のデータ型を OpenSearch にマッピングする](full-text-search-non-string-indexing-mapping.md)
+ [データマッピングの検証](full-text-search-data-validation.md)
+ [Neptune での非文字列 OpenSearch クエリの例](full-text-search-non-string-examples.md)
  + [年齢が 30 より大きく、名前が「Si」で始まるすべての頂点を取得します。](full-text-search-non-string-examples.md#full-text-search-non-string-example-1)
  + [年齢が 10 から 50 までのノードをすべて取得し、「Ronka」とあいまい一致の名前を取得する](full-text-search-non-string-examples.md#full-text-search-non-string-example-2)
  + [過去 25 日以内のタイムスタンプを持つすべてのノードを取得する](full-text-search-non-string-examples.md#full-text-search-non-string-example-3)
  + [特定の年と月以内のタイムスタンプを持つすべてのノードを取得する](full-text-search-non-string-examples.md#full-text-search-non-string-example-4)

# 既存の Neptune フルテキスト検索スタックを更新して、非文字列インデックスをサポートする
<a name="full-text-search-non-string-indexing-update"></a>

既に Neptune 全文検索を使用している場合は、非文字列インデックスをサポートするために必要な手順は次のとおりです。

1. **ストリームポーラーの Lambda 関数を停止します。**これにより、エクスポート中に新しい更新がコピーされなくなります。これを行うには、Lambda 関数を呼び出すクラウドイベントルールを無効にします。
   + AWS マネジメントコンソール で CloudWatch に移動します。
   + **[Rules]** (ルール) を選択します。
   + Lambda ストリームポーラー名のルールを選択します。
   + **[disable]** (無効) を選択して、ルールを一時的に無効にします。

1. **OpenSearch で現在の Neptune インデックスを削除します。**次の `curl` クエリを使用して、OpenSearch クラスターから `amazon_neptune` インデックスを削除します。

   ```
   curl -X DELETE "your OpenSearch endpoint/amazon_neptune"
   ```

1. **Neptune から OpenSearch へ 1 回限りのエクスポートを開始します。**この時点で新しい OpenSearch スタックをセットアップするのが最善です。そうすれば、エクスポートを実行するポーラーに対して新しいアーティファクトが取得されるようになります。

   [GitHub のここ]( https://github.com/awslabs/amazon-neptune-tools/blob/master/export-neptune-to-elasticsearch/readme.md)で一覧表示されている手順に従って、Neptune から OpenSearch へのデータの 1 回限りのエクスポートを開始します。

1. **既存のストリームポーラーの Lambda アーティファクトを更新します。**Neptune のデータを OpenSearch へのエクスポートが正常に完了した後、次のステップを実行します。
   + AWS マネジメントコンソール で、CloudFormation に移動します。
   + メインの親 CloudFormation スタックを選択します。
   + スタックの**[Update]** (更新) オプションを選択します。
   + **[Replace current template]** (現在のテンプレートを置換) オプションを選択します。
   + テンプレートソースの場合、**Amazon S3 URL** を選択します。
   + Amazon S3 URL に、次のように入力します。

     ```
     https://aws-neptune-customer-samples.s3.amazonaws.com/neptune-stream/neptune_to_elastic_search.json
     ```
   + CloudFormation パラメータを何も変更せずに **[Next]** (次へ) を選択します。
   + **[Update stack]** (スタックの更新) を選択すると、CloudFormation がストリームポーラーの Lambda コードアーティファクトを最新のアーティファクトに置き換えます。

1. **ストリームポーラーを再度開始します。**これを行うには、適切な CloudWatch ルールを有効にします。
   + AWS マネジメントコンソール で CloudWatch に移動します。
   + **[Rules]** (ルール) を選択します。
   + Lambda ストリームポーラー名のルールを選択します。
   + **[enable]** (有効化) を選択します。

# Neptune 全文検索でインデックス付けされるフィールドのフィルタリング
<a name="full-text-search-non-string-indexing-filters"></a>

CloudFormation テンプレートには 2 つのフィールドがあり、OpenSearch インデックス作成から除外するプロパティキー、述語キー、またはデータ型を指定できる詳細があります。

## プロパティまたは述語名でフィルタリングする
<a name="full-text-search-non-string-indexing-filters-name"></a>

OpenSearch インデックス作成から除外するプロパティキーまたは述語キーのコンマ区切りリストを提供するための `Properties to exclude from being inserted into Elastic Search Index` という名前のオプションの CloudFormation テンプレートパラメータを使用できます。

たとえば、このパラメータを `bob` に設定したとします。

```
"Properties to exclude from being inserted into Elastic Search Index" : bob
```

その場合、次の Gremlin 更新クエリのストリームレコードは、インデックスに入るのではなく削除されます。

```
g.V("1").property("bob", "test")
```

同様に、パラメータを `http://my/example#bob` に設定することもできます。

```
"Properties to exclude from being inserted into Elastic Search Index" : http://my/example#bob
```

その場合、次の SPARQL 更新クエリのストリームレコードは、インデックスに入るのではなく削除されます。

```
PREFIX ex: <http://my/example#>
INSERT DATA { ex:s1 ex:bob "test"}.
```

この CloudFormation テンプレートパラメータに何も入力しなければ、除外されない限りすべてのプロパティキーにインデックスが付けられます。

## プロパティまたは述語値型でフィルタリングする
<a name="full-text-search-non-string-indexing-filters-datatype"></a>

OpenSearch インデックス作成から除外するプロパティまたは述語値データ型のコンマ区切りリストを指定するための `Datatypes to exclude from being inserted into Elastic Search Index` という名前のオプションの CloudFormation テンプレートパラメータを使用できます。

SPARQL の場合、完全な XSD 型 URI を一覧表示する必要はなく、データ型トークンを一覧表示するだけで済みます。一覧表示できる有効なデータ型トークンは次のとおりです。
+ `string`
+ `boolean`
+ `float`
+ `double`
+ `dateTime`
+ `date`
+ `time`
+ `byte`
+ `short`
+ `int`
+ `long`
+ `decimal`
+ `integer`
+ `nonNegativeInteger`
+ `nonPositiveInteger`
+ `negativeInteger`
+ `unsignedByte`
+ `unsignedShort`
+ `unsignedInt`
+ `unsignedLong`

Gremlin の場合、一覧表示する有効なデータ型は次のとおりです。
+ `string`
+ `date`
+ `bool`
+ `byte`
+ `short`
+ `int`
+ `long`
+ `float`
+ `double`

たとえば、このパラメータを `string` に設定したとします。

```
"Datatypes to exclude from being inserted into Elastic Search Index" : string
```

その場合、次の Gremlin 更新クエリのストリームレコードは、インデックスに入るのではなく削除されます。

```
g.V("1").property("myStringval", "testvalue")
```

同様に、パラメータを `int` に設定することもできます。

```
"Datatypes to exclude from being inserted into Elastic Search Index" : int
```

その場合、次の SPARQL 更新クエリのストリームレコードは、インデックスに入るのではなく削除されます。

```
PREFIX ex: <http://my/example#>
PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>
INSERT DATA { ex:s1 ex:bob "11"^^xsd:int }.
```

この CloudFormation テンプレートパラメータに何も入力しなかった場合、値を安全に OpenSearch に変換できるすべてのプロパティにインデックスが付けられます。クエリ言語でサポートされていないリストされた型は無視されます。

# SPARQL および Gremlin のデータ型を OpenSearch にマッピングする
<a name="full-text-search-non-string-indexing-mapping"></a>

OpenSearch での新しいデータ型マッピングは、プロパティまたはオブジェクトで使用されているデータ型に基づいて作成されます。一部のフィールドには異なる種類の値が含まれているため、初期マッピングではフィールドの一部の値が除外される場合があります。

Neptune データ型は OpenSearch データ型に次のようにマッピングされます。


| SPARQL 型 | Gremlin 型 | OpenSearch の型 | 
| --- | --- | --- | 
|  `XSD:int` `XSD:unsignedInt` `XSD:integer` `XSD:byte` `XSD:unsignedByte` `XSD:short` `XSD:unsignedShort` `XSD:long` `XSD:unsignedLong`  |  `byte` `short` `int` `long`  | `long` | 
|  `XSD:float` `XSD:double` `XSD:decimal`  |  `float` `double`  | `double` | 
| `XSD:boolean` | `bool` | `boolean` | 
|  `XSD:datetime` `XSD:date`  | `date` | `date` | 
|  `XSD:string` `XSD:time`  | `string` | `text` | 
| *カスタムデータ型* | *(N/A*) | `text` | 
| *その他のデータ型* | *(N/A*) | `text` | 

たとえば、次の Gremlin 更新クエリでは、「newField」の新しいマッピングが OpenSearch に追加され、すなわち、`{ "type" : "double" }` になります。

```
g.V("1").property("newField" 10.5)
```

同様に、次の SPARQL 更新クエリでは、「ex:byte」の新しいマッピングが OpenSearch に追加され、すなわち、`{ "type" : "long" }` になります。

```
PREFIX ex: <http://my/example#>
PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>

INSERT DATA { ex:test ex:byte "123"^^xsd:byte }.
```

**注記**  
ご覧のとおり、Neptune から OpenSearch にマッピングされた項目は、OpenSearch では Neptune にあるものとは別のデータ型になる可能性があります。ただし、OpenSearch には明示的なテキストフィールド、「datatype」があり、Neptune でその項目が持つデータ型を記録します。

# データマッピングの検証
<a name="full-text-search-data-validation"></a>



このプロセスを使用して、データは Neptune から OpenSearch にレプリケートされます。
+ 問題のフィールドのマッピングが既に OpenSearch に存在する場合:
  + データ検証ルールを使用してデータを既存のマッピングに安全に変換できる場合は、フィールドを OpenSearch に格納します。
  + そうでない場合は、対応するストリーム更新レコードを削除します。
+ 問題のフィールドに既存のマッピングがない場合は、Neptune のフィールドのデータ型に対応する OpenSearch データ型を見つけます。
  + データ検証ルールを使用してそのフィールドデータを OpenSearch データ型に安全に変換できる場合は、新しいマッピングおよびフィールドデータを OpenSearch に格納します。
  + そうでない場合は、対応するストリーム更新レコードを削除します。

値は Neptune 型ではなく同等の OpenSearch 型または既存の OpenSearch マッピングに対して検証されます。たとえば、`"123"^^xsd:int` の値 `"123"` の検証が `int` 型ではなく `long` 型に対して行われます。

Neptune はすべてのデータを OpenSearch にレプリケートしようとしますが、OpenSearch のデータ型が Neptune のものとは全く異なっている場合があり、そのような場合、レコードは OpenSearch でインデックス化されるのではなく、スキップされます。

たとえば、Neptune では、1 つのプロパティが異なる型の複数の値を持つことがありますが、OpenSearch では、フィールドは、インデックス全体で同じ型である必要があります。

デバッグログを有効にすると、Neptune から OpenSearch へのエクスポート中に削除されたレコードを表示できます。デバッグログエントリの例を次に示します。

```
Dropping Record : Data type not a valid Gremlin type 
<Record>
```

データ型は、次のように検証されます。
+ **`text`** — Neptune のすべての値は、OpenSearch のテキストに安全にマッピングできます。
+ **`long`** — 次の Neptune データ型のルールは、OpenSearch マッピング型が long の場合に当てはまります (以下の例では、`"testLong"` は `long` マッピング型を持つとみなされています）。
  + `boolean` — 無効で、変換できない、対応するストリーム更新レコードが削除されます。

    無効な Gremlin の例は次のとおりです。

    ```
      "testLong" : true.
      "testLong" : false.
    ```

    無効な SPARQL の例は次のとおりです。

    ```
      ":testLong" : "true"^^xsd:boolean
      ":testLong" : "false"^^xsd:boolean
    ```
  + `datetime` — 無効で、変換できない、対応するストリーム更新レコードは削除されます。

    無効な Gremlin の例は次のとおりです。

    ```
      ":testLong" :  datetime('2018-11-04T00:00:00').
    ```

    無効な SPARQL の例は次のとおりです。

    ```
      ":testLong" : "2016-01-01"^^xsd:date
    ```
  + `float`、`double`、または `decimal` — Neptune での値が 64 ビットに収まる整数である場合、その値は有効であり、長整数として OpenSearch に格納されますが、分数部を持つ場合、または `NaN` あるいは `INF` である場合、または、9,223,372,036,854,775,807 より大きいか、-9,223,372,036,854,775,808 より小さい場合、その値は無効であり、対応するストリーム更新レコードは削除されます。

    有効な Gremlin の例は次のとおりです。

    ```
      "testLong" :  145.0.
      ":testLong" :  123
      ":testLong" :  -9223372036854775807
    ```

    有効な SPARQL の例は次のとおりです。

    ```
      ":testLong" : "145.0"^^xsd:float
      ":testLong" :  145.0
      ":testLong" : "145.0"^^xsd:double
      ":testLong" : "145.0"^^xsd:decimal
      ":testLong" : "-9223372036854775807"
    ```

    無効な Gremlin の例は次のとおりです。

    ```
      "testLong" :  123.45
      ":testLong" :  9223372036854775900
    ```

    無効な SPARQL の例は次のとおりです。

    ```
      ":testLong" :  123.45
      ":testLong" :  9223372036854775900
      ":testLong" : "123.45"^^xsd:float
      ":testLong" : "123.45"^^xsd:double
      ":testLong" : "123.45"^^xsd:decimal
    ```
  + `string` — Neptune での値が 64 ビット整数に含まれる可能性がある整数の文字列表現である場合、その値は有効であり、OpenSearch で `long` に変換されます。他の文字列値は `long` マッピングには無効であり、対応するストリーム更新レコードは削除されます。

    有効な Gremlin の例は次のとおりです。

    ```
      "testLong" :  "123".
      ":testLong" :  "145.0"
      ":testLong" :  "-9223372036854775807"
    ```

    有効な SPARQL の例は次のとおりです。

    ```
      ":testLong" : "145.0"^^xsd:string
      ":testLong" : "-9223372036854775807"^^xsd:string
    ```

    無効な Gremlin の例は次のとおりです。

    ```
      "testLong" :  "123.45"
      ":testLong" :  "9223372036854775900"
      ":testLong" :  "abc"
    ```

    無効な SPARQL の例は次のとおりです。

    ```
      ":testLong" : "123.45"^^xsd:string
      ":testLong" : "abc"
      ":testLong" : "9223372036854775900"^^xsd:string
    ```
+ **`double`** — OpenSearch マッピング型が `double` の場合、以下の規則が適用されます (ここで「testDouble」フィールドは、OpenSearch で `double` のマッピングを持つとみなされます)。
  + `boolean` — 無効で、変換できない、対応するストリーム更新レコードが削除されます。

    無効な Gremlin の例は次のとおりです。

    ```
      "testDouble" : true.
      "testDouble" : false.
    ```

    無効な SPARQL の例は次のとおりです。

    ```
      ":testDouble" : "true"^^xsd:boolean
      ":testDouble" : "false"^^xsd:boolean
    ```
  + `datetime` — 無効で、変換できない、対応するストリーム更新レコードは削除されます。

    無効な Gremlin の例は次のとおりです。

    ```
      ":testDouble" :  datetime('2018-11-04T00:00:00').
    ```

    無効な SPARQL の例は次のとおりです。

    ```
      ":testDouble" : "2016-01-01"^^xsd:date
    ```
  + 浮動小数点型 `NaN` または `INF` — SPARQL の値が浮動小数点 `NaN` または `INF` の場合、これは有効ではなく、対応するストリーム更新レコードは削除されます。

    無効な SPARQL の例は次のとおりです。

    ```
    "  :testDouble" : "NaN"^^xsd:float
      ":testDouble" : "NaN"^^double
      ":testDouble" : "INF"^^double
      ":testDouble" : "-INF"^^double
    ```
  + 数値または数値文字列 — Neptune での値が、`double` として安全に表現できる他の数値または数値文字列表現である場合、それは有効であり、OpenSearch で `double` に変換されます。その他の文字列値は、OpenSearch `double` マッピングでは無効であり、対応するストリーム更新レコードは削除されます。

    有効な Gremlin の例は次のとおりです。

    ```
      "testDouble" :  123
      ":testDouble" :  "123"
      ":testDouble" :  145.67
      ":testDouble" :  "145.67"
    ```

    有効な SPARQL の例は次のとおりです。

    ```
      ":testDouble" :  123.45
      ":testDouble" :  145.0
      ":testDouble" : "123.45"^^xsd:float
      ":testDouble" : "123.45"^^xsd:double
      ":testDouble" : "123.45"^^xsd:decimal
      ":testDouble" : "123.45"^^xsd:string
    ```

    無効な Gremlin の例は次のとおりです。

    ```
      ":testDouble" :  "abc"
    ```

    無効な SPARQL の例は次のとおりです。

    ```
      ":testDouble" : "abc"
    ```
+ **`date`** — OpenSearch マッピング型が `date` である場合、Neptune の `date` および `dateTime` 値は有効であり、`dateTime` 形式に正常に解析できる任意の文字列値も同様です。

  Gremlin または SPARQL の有効な例は次のとおりです。

  ```
    Date(2016-01-01)
    "2016-01-01" "
    2003-09-25T10:49:41"
    "2003-09-25T10:49"
    "2003-09-25T10"
    "20030925T104941-0300"
    "20030925T104941"
    "2003-Sep-25" "
    Sep-25-2003"
    "2003.Sep.25"
    "2003/09/25"
    "2003 Sep 25" "
    Wed, July 10, '96"
    "Tuesday, April 12, 1952 AD 3:30:42pm PST"
    "123"
    "-123"
    "0"
    "-0"
    "123.00"
    "-123.00"
  ```

  無効な例は次のとおりです。

  ```
    123.45
    True
    "abc"
  ```

# Neptune での非文字列 OpenSearch クエリの例
<a name="full-text-search-non-string-examples"></a>

Neptune は現在、OpenSearch 範囲クエリを直接はサポートしていません。ただし、次のサンプルクエリに示すように、Lucene 構文と query-type="query\$1string" を使用して同じ効果を得ることができます。

## 年齢が 30 より大きく、名前が「Si」で始まるすべての頂点を取得します。
<a name="full-text-search-non-string-example-1"></a>

Gremlin の場合:

```
g.withSideEffect('Neptune#fts.endpoint', 'http://your-es-endpoint')
 .withSideEffect("Neptune#fts.queryType", "query_string")
 .V().has('*', 'Neptune#fts predicates.age.value:>30 && predicates.name.value:Si*');
```

SPARQL の場合:

```
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX neptune-fts: <http://aws.amazon.com/neptune/vocab/v01/services/fts#>
SELECT * WHERE {
  SERVICE neptune-fts:search {
    neptune-fts:config neptune-fts:endpoint 'http://localhost:9200' .
    neptune-fts:config neptune-fts:queryType 'query_string' .
    neptune-fts:config neptune-fts:query "predicates.\\*foaf\\*age.value:>30 AND predicates.\\*foaf\\*name.value:Si*" .
    neptune-fts:config neptune-fts:field '*' .
    neptune-fts:config neptune-fts:return ?res .
  }
}
```

ここで、簡潔にするために、`"\\*foaf\\*age` は完全な URI の代わりに使用されます。この正規表現では、URI に `foaf` および `age` の両方があるすべてのフィールドが取得されます。

## 年齢が 10 から 50 までのノードをすべて取得し、「Ronka」とあいまい一致の名前を取得する
<a name="full-text-search-non-string-example-2"></a>

Gremlin の場合:

```
g.withSideEffect('Neptune#fts.endpoint', 'http://your-es-endpoint')
 .withSideEffect("Neptune#fts.queryType", "query_string")
 .V().has('*', 'Neptune#fts predicates.age.value:[10 TO 50] AND predicates.name.value:Ronka~');
```

SPARQL の場合:

```
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX neptune-fts: <http://aws.amazon.com/neptune/vocab/v01/services/fts#>
SELECT * WHERE {
  SERVICE neptune-fts:search {
    neptune-fts:config neptune-fts:endpoint 'http://localhost:9200' .
    neptune-fts:config neptune-fts:queryType 'query_string' .
    neptune-fts:config neptune-fts:query "predicates.\\*foaf\\*age.value:[10 TO 50] AND predicates.\\*foaf\\*name.value:Ronka~" .
    neptune-fts:config neptune-fts:field '*' .
    neptune-fts:config neptune-fts:return ?res .
  }
}
```

## 過去 25 日以内のタイムスタンプを持つすべてのノードを取得する
<a name="full-text-search-non-string-example-3"></a>

Gremlin の場合:

```
g.withSideEffect('Neptune#fts.endpoint', 'http://your-es-endpoint')
 .withSideEffect("Neptune#fts.queryType", "query_string")
 .V().has('*', 'Neptune#fts predicates.timestamp.value:>now-25d');
```

SPARQL の場合:

```
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX neptune-fts: <http://aws.amazon.com/neptune/vocab/v01/services/fts#>
SELECT * WHERE {
SELECT * WHERE {
  SERVICE neptune-fts:search {
    neptune-fts:config neptune-fts:endpoint 'http://localhost:9200' .
    neptune-fts:config neptune-fts:queryType 'query_string' .
    neptune-fts:config neptune-fts:query "predicates.\\*foaf\\*timestamp.value:>now-25d~" .
    neptune-fts:config neptune-fts:field '*' .
    neptune-fts:config neptune-fts:return ?res .
  }
}
```

## 特定の年と月以内のタイムスタンプを持つすべてのノードを取得する
<a name="full-text-search-non-string-example-4"></a>

Gremlin では、Lucene構文の[日付の数式](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/common-options.html#date-math)、2020年 12 月は次のようになります。

```
g.withSideEffect('Neptune#fts.endpoint', 'http://your-es-endpoint')
 .withSideEffect("Neptune#fts.queryType", "query_string")
 .V().has('*', 'Neptune#fts predicates.timestamp.value:>2020-12');
```

グレムリンの代替案:

```
g.withSideEffect('Neptune#fts.endpoint', 'http://your-es-endpoint')
 .withSideEffect("Neptune#fts.queryType", "query_string")
 .V().has('*', 'Neptune#fts predicates.timestamp.value:[2020-12 TO 2021-01]');
```