

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 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\$150세이고 이름이 '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 Management Console에서 CloudWatch로 이동합니다.
   + **규칙**을 선택합니다.
   + Lambda 스트림 폴러 이름이 있는 규칙을 선택합니다.
   + 규칙을 일시적으로 비활성화하려면 **비활성화**를 선택합니다.

1. **OpenSearch에서 현재 Neptune 인덱스를 삭제합니다.** 다음 `curl` 쿼리를 사용하여 OpenSearch 클러스터에서 `amazon_neptune` 인덱스를 삭제하세요.

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

1. **Neptune에서 OpenSearch로 일회성 내보내기를 시작합니다.** 이 시점에서 새 OpenSearch 스택을 설정하여 내보내기를 수행하는 폴러가 새 아티팩트를 선택할 수 있도록 하는 것이 가장 좋습니다.

   [여기 GitHub]( https://github.com/awslabs/amazon-neptune-tools/blob/master/export-neptune-to-elasticsearch/readme.md)에 나열된 단계에 따라 Neptune 데이터를 OpenSearch로 한 번 내보내는 작업을 시작하세요.

1. **기존 스트림 폴러의 Lambda 아티팩트를 업데이트합니다.** OpenSearch로 Neptune 데이터를 성공적으로 내보낸 후 다음 단계를 수행하세요.
   + AWS Management Console에서 CloudFormation으로 이동합니다.
   + 기본 상위 CloudFormation 스택을 선택합니다.
   + 스택의 **업데이트** 옵션을 선택합니다.
   + **옵션에서 현재 템플릿 교체**를 선택합니다.
   + 템플릿 소스에서 **Amazon S3 URL**을 선택합니다.
   + Amazon S3 URL의 경우 다음과 같이 입력합니다.

     ```
     https://aws-neptune-customer-samples.s3.amazonaws.com/neptune-stream/neptune_to_elastic_search.json
     ```
   + CloudFormation 파라미터를 변경하지 않고 **다음**을 선택합니다.
   + **스택 업데이트**를 선택합니다. CloudFormation에서는 스트림 폴러의 Lambda 코드 아티팩트를 최신 아티팩트로 대체합니다.

1. **스트림 폴러를 다시 시작합니다.** 적절한 CloudWatch 규칙을 활성화하여 이를 수행하세요.
   + AWS Management Console에서 CloudWatch로 이동합니다.
   + **규칙**을 선택합니다.
   + Lambda 스트림 폴러 이름이 있는 규칙을 선택합니다.
   + **활성화**를 선택합니다.

# Neptune 전체 텍스트 검색에서 인덱싱되는 필드 필터링
<a name="full-text-search-non-string-indexing-filters"></a>

CloudFormation 템플릿 세부 정보에는 OpenSearch 인덱싱에서 제외할 속성이나 조건부 키 또는 데이터 유형을 지정할 수 있는 2개의 필드가 있습니다.

## 속성 또는 조건자 이름을 기준으로 필터링
<a name="full-text-search-non-string-indexing-filters-name"></a>

`Properties to exclude from being inserted into Elastic Search Index`로 이름이 지정된 옵션 CloudFormation 템플릿 파라미터를 사용하여 OpenSearch 인덱싱에서 제외할 속성 또는 조건부 키를 쉼표로 구분된 목록으로 제공할 수 있습니다.

예를 들어, 이 파라미터를 `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>

`Datatypes to exclude from being inserted into Elastic Search Index`로 이름이 지정된 옵션 CloudFormation 템플릿 파라미터를 사용하여 OpenSearch 인덱싱에서 제외할 속성 또는 조건부 값 데이터 유형을 쉼표로 구분된 목록으로 제공할 수 있습니다.

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로 매핑된 항목은 결국 Neptune과 OpenSearch에서 데이터 유형이 다르게 나타날 수 있습니다. 하지만 OpenSearch에는 Neptune에 있는 항목의 데이터 유형을 기록하는 명시적인 텍스트 필드인 'datatype'이 있습니다.

# 데이터 매핑 검증
<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에서는 한 속성에 유형이 다른 여러 값이 있을 수 있지만, OpenSearch의 필드는 인덱스 전체에서 유형이 같아야 합니다.

디버그 로그를 활성화하면 Neptune에서 OpenSearch로 내보내는 동안 삭제된 레코드를 볼 수 있습니다. 디버그 로그 항목의 예는 다음과 같습니다.

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

데이터 유형은 다음과 같이 검증됩니다.
+ **`text`**   –   Neptune의 모든 값을 OpenSearch의 텍스트에 안전하게 매핑할 수 있습니다.
+ **`long`**   –   OpenSearch 매핑 유형이 긴 경우 Neptune 데이터 유형에 대한 다음 규칙이 적용됩니다(아래 예에서는 `"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에 long으로 저장됩니다. 그러나 소수 부분이 있거나, `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`으로 변환됩니다. 다른 모든 문자열 값은 Elasticseearch `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`인 경우 다음 규칙이 적용됩니다(여기서는 OpenSearch에서 'testDouble' 필드에 `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 .
  }
}
```

여기서는 간결성을 위해 전체 URI 대신 `"\\*foaf\\*age`가 사용됩니다. 이 정규 표현식은 URI에서 `foaf` 및 `age`가 있는 모든 필드를 검색합니다.

## 나이가 10\$150세이고 이름이 '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');
```

Gremlin의 대안:

```
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]');
```