

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Extensions OpenCypher dans Amazon Neptune
<a name="access-graph-opencypher-extensions"></a>

 Amazon Neptune prend en charge la version 9 de référence de la spécification OpenCypher. Reportez-vous [Conformité aux spécifications OpenCypher dans Amazon Neptune](feature-opencypher-compliance.md) à Amazon Neptune pour plus de détails. En outre, Amazon Neptune prend en charge les fonctionnalités répertoriées ici. À moins que des versions spécifiques ne soient mentionnées, les fonctionnalités sont disponibles dans Neptune Database et Neptune Analytics. 

## Accès aux données S3 au moment de la requête
<a name="opencypher-compliance-neptune-read"></a>

Disponible dans Neptune Database 1.4.7.0 et versions ultérieures.

Neptune prend en charge la `neptune.read()` fonction permettant de lire les données CSV ou Parquet d'Amazon S3 directement dans les requêtes OpenCypher. Contrairement au chargeur groupé qui importe les données avant de les interroger, il `neptune.read()` accède aux données Amazon S3 au moment de l'exécution de la requête.

Pour une documentation complète, voir[neptune.read ()](access-graph-opencypher-21-extensions-s3-read.md).

## Fonction `join()` spécifique à Neptune
<a name="opencypher-compliance-join-function"></a>

Disponible dans Neptune Database et Neptune Analytics.

Neptune implémente une fonction `join()` qui ne se trouve pas dans la spécification openCypher. Cela crée un littéral de chaîne à partir d'une liste de littéraux de chaîne et d'un délimiteur de chaîne. Deux arguments sont donc utilisés :
+ Le premier argument est une liste de littéraux de chaîne.
+ Le deuxième argument est le délimiteur de chaîne, qui peut avoir un, aucune ou plusieurs caractères.

Exemple :

```
join(["abc", "def", "ghi"], ", ")    // Returns "abc, def, ghi"
```

## Fonction `removeKeyFromMap()` spécifique à Neptune
<a name="opencypher-compliance-removeKeyFromMap-function"></a>

Disponible dans Neptune Database et Neptune Analytics.

Neptune implémente une fonction `removeKeyFromMap()` qui ne se trouve pas dans la spécification openCypher. Il supprime une clé spécifiée dans un mappage et renvoie le nouveau mappage généré.

La fonction accepte deux arguments :
+ Le premier argument est le mappage à partir duquel la clé doit être supprimée.
+ Le premier argument est la clé à supprimer du mappage.

Cette fonction `removeKeyFromMap()` est particulièrement utile dans les situations où vous souhaitez définir les valeurs d'un nœud ou d'une relation en déroulant une liste de mappage. Par exemple :

```
UNWIND [{`~id`: 'id1', name: 'john'}, {`~id`: 'id2', name: 'jim'}] as val
CREATE (n {`~id`: val.`~id`})
SET n = removeKeyFromMap(val, '~id')
```

## Valeurs d'ID personnalisées pour les propriétés des nœuds et des relations
<a name="opencypher-compliance-custom-ids"></a>

Disponible dans Neptune Database 1.2.0.2 et versions ultérieures, et dans Neptune Analytics.

À partir de la [version 1.2.0.2 du moteur](engine-releases-1.2.0.2.md), Neptune a étendu la spécification openCypher afin que vous puissiez désormais spécifier les valeurs `id` des nœuds et des relations dans les clauses `CREATE`, `MERGE` et `MATCH`. Cela vous permet d'attribuer des chaînes conviviales plutôt que des chaînes générées par le système UUIDs pour identifier les nœuds et les relations.

Dans Neptune Analytics, les valeurs d'identification personnalisées ne sont pas disponibles pour les bords.

**Avertissement**  
Cette extension de la spécification openCypher est rétrocompatible, car `~id` est désormais considéré comme un nom de propriété réservé. Si vous l'utilisez déjà `~id` en tant que propriété dans vos données et requêtes, vous devez migrer la propriété existante vers une nouvelle clé de propriété et supprimer l'ancienne. Consultez [Que faire si vous utilisez actuellement `~id` en tant que propriété](#opencypher-compliance-custom-ids-migrating).

Voici un exemple montrant comment créer des nœuds et des relations dotés d'ID personnalisés :

```
CREATE (n {`~id`: 'fromNode', name: 'john'})
  -[:knows {`~id`: 'john-knows->jim', since: 2020}]
  ->(m {`~id`: 'toNode', name: 'jim'})
```

Si vous essayez de créer un ID personnalisé déjà utilisé, Neptune génère une erreur `DuplicateDataException`.

Voici un exemple d'utilisation d'ID personnalisé dans une clause `MATCH` :

```
MATCH (n {`~id`: 'id1'})
RETURN n
```

Voici un exemple d'utilisation de la personnalisation IDs dans une `MERGE` clause :

```
MATCH (n {name: 'john'}), (m {name: 'jim'})
MERGE (n)-[r {`~id`: 'john->jim'}]->(m)
RETURN r
```

### Que faire si vous utilisez actuellement `~id` en tant que propriété
<a name="opencypher-compliance-custom-ids-migrating"></a>

Avec la [version 1.2.0.2 du moteur](engine-releases-1.2.0.2.md), la clé `~id` dans les clauses openCypher est désormais traitée comme `id` plutôt que comme propriété. Dès lors, si vous avez une propriété nommée `~id`, il devient impossible d'y accéder.

Si vous utilisez une propriété `~id`, avant de passer à la version de moteur `1.2.0.2` ou à une version ultérieure, vous devez migrer la propriété `~id` existante vers une nouvelle clé de propriété, puis supprimer la propriété `~id`. Par exemple, la requête ci-dessous :
+ Crée une propriété nommée 'newId' pour tous les nœuds,
+ copie la valeur de la propriété '\$1id' dans la propriété 'newId'
+ et supprime la propriété '\$1id' des données

```
MATCH (n)
WHERE exists(n.`~id`)
SET n.newId = n.`~id`
REMOVE n.`~id`
```

La même approche doit être adoptée pour toutes les relations dans les données qui ont une propriété `~id`.

Vous devrez également modifier toutes les requêtes que vous utilisez qui font référence à une propriété `~id`. Par exemple, cette requête :

```
MATCH (n)
WHERE n.`~id` = 'some-value'
RETURN n
```

... serait remplacée par ce qui suit :

```
MATCH (n)
WHERE n.newId = 'some-value'
RETURN n
```

## Support des sous-requêtes CALL dans Neptune
<a name="call-subquery-support"></a>

 Disponible dans Neptune Database 1.4.1.0 et versions ultérieures, et dans Neptune Analytics. 

 Amazon Neptune prend en charge `CALL` les sous-requêtes. Une `CALL` sous-requête est une partie de la requête principale qui s'exécute dans une portée isolée pour chaque entrée de la `CALL` sous-requête. 

 Supposons, par exemple, qu'un graphique contienne des données sur les personnes, leurs amis et les villes dans lesquelles elles vivaient. Nous pouvons retrouver les deux plus grandes villes où vivait chaque ami d'une personne en utilisant une `CALL` sous-requête : 

```
MATCH (person:Person)-[:knows]->(friend) 
CALL { 
  WITH friend 
  MATCH (friend)-[:lived_in]->(city) 
  RETURN city 
  ORDER BY city.population DESC
  LIMIT 2 
} 
RETURN person, friend, city
```

 Dans cet exemple, la partie requête interne `CALL { ... }` est exécutée pour chaque `friend` élément correspondant à la clause MATCH précédente. Lorsque la requête interne est exécutée, les `LIMIT` clauses `ORDER` and sont locales aux villes où vivait un ami en particulier. Nous obtenons donc (au maximum) deux villes par ami. 

 Toutes les clauses de requête sont disponibles dans les `CALL` sous-requêtes. Cela inclut également les `CALL` sous-requêtes imbriquées. Certaines restrictions relatives à la première `WITH` clause et aux variables émises existent et sont expliquées ci-dessous. 

### Étendue des variables dans la sous-requête CALL
<a name="variable-scope-inside-call-subquery"></a>

 Les variables des clauses situées avant la `CALL` sous-requête et utilisées à l'intérieur de celle-ci doivent être importées par la `WITH` clause initiale. Contrairement aux `WITH` clauses ordinaires, elle ne peut contenir qu'une liste de variables, mais elle n'autorise pas l'aliasing et ne peut pas être utilisée avec `DISTINCT``ORDER BY`,`WHERE`,`SKIP`, ou`LIMIT`. 

### Variables renvoyées par la sous-requête CALL
<a name="variables-returned-call-subquery"></a>

 Les variables émises par la `CALL` sous-requête sont spécifiées dans la `RETURN` clause finale. Notez que les variables émises ne peuvent pas se chevaucher avec les variables avant la `CALL` sous-requête. 

### Limitations
<a name="call-subquery-limitations"></a>

 À l'heure actuelle, les mises à jour au sein d'une `CALL` sous-requête ne sont pas prises en charge. 

## Fonctions Neptune OpenCypher
<a name="opencypher-compliance-new-functions"></a>

 Disponible dans Neptune Database 1.4.1.0 et versions ultérieures, et dans Neptune Analytics. 

**textIndexOf**

 `textIndexOf(text :: STRING, lookup :: STRING, from = 0 :: INTEGER?, to = -1 :: INTEGER?) :: (INTEGER?)` 

 Renvoie l'indice de la première occurrence comprise entre le `text` décalage `from` (inclus) et le décalage `to` (exclusif). `lookup` Si la `to` valeur est -1, la plage continue jusqu'à la fin de`text`. L'indexation est basée sur zéro et est exprimée en valeurs scalaires Unicode (points de code non substituts). 

```
RETURN textIndexOf('Amazon Neptune', 'e')
{
  "results": [{
      "textIndexOf('Amazon Neptune', 'e')": 8
    }]
}
```

**collToSet**

 `collToSet(values :: LIST OF ANY?) :: (LIST? OF ANY?)` 

 Renvoie une nouvelle liste contenant uniquement les éléments uniques de la liste d'origine. L'ordre de la liste d'origine est **conservé** (par exemple, les `[1, 6, 5, 1, 5]` retours`[1, 6, 5]`). 

```
RETURN collToSet([1, 6, 5, 1, 1, 5])
{
  "results": [{
      "collToSet([1, 6, 5, 1, 1, 5])": [1, 6, 5]
    }]
}
```

**CollSubtract**

 `collSubtract(first :: LIST OF ANY?, second :: LIST OF ANY?) :: (LIST? OF ANY?)` 

 Renvoie une nouvelle liste contenant tous les éléments uniques dont les éléments sont `first` exclus`second`. 

```
RETURN collSubtract([2, 5, 1, 0], [1, 5])
{
  "results": [{
      "collSubtract([2, 5, 1, 0], [1, 5])": [0, 2]
    }]
}
```

**Intersection de Coll**

 `collIntersection(first :: LIST? OF ANY?, second :: LIST? OF ANY?) :: (LIST? OF ANY?)` 

 Renvoie une nouvelle liste contenant tous les éléments uniques de l'intersection de `first` et`second`. 

```
RETURN collIntersection([2, 5, 1, 0], [1, 5])
{
  "results": [{
      "collIntersection([2, 5, 1, 0], [1, 5])": [1, 5]
    }]
}
```

## Fonctions de tri
<a name="sorting-functions"></a>

 Les sections suivantes définissent les fonctions permettant de trier les collections. Ces fonctions utilisent (dans certains cas facultatifs) des arguments de `config` carte, ou une liste de plusieurs cartes de ce type, qui définissent la clé de tri et and/or le sens du tri : 

```
{ key: STRING, order: STRING }
```

 `key`Voici une propriété de carte ou de nœud dont la valeur doit être utilisée pour le tri. `order`est « » ou `asc` « `desc` » (sans distinction majuscules/minuscules) pour spécifier un tri croissant ou décroissant, respectivement. Par défaut, le tri sera effectué par ordre croissant. 

**Coll Sort**

 `collSort(coll :: LIST OF ANY, config :: MAP?) :: (LIST? OF ANY?)` 

 Renvoie une nouvelle liste triée contenant les éléments de la liste `coll` d'entrée. 

```
RETURN collSort([5, 3, 1], {order: 'asc'})
{
  "results": [{
      "collSort([5, 3, 1])": [1, 3, 5]
    }]
}
```

**collSortMaps**

 `collSortMaps(coll :: LIST OF MAP, config :: MAP) :: (LIST? OF ANY?)` 

 Renvoie une liste de cartes triées en fonction de la valeur de la `key` propriété spécifiée. 

```
RETURN collSortMaps([{name: 'Alice', age: 25}, {name: 'Bob', age: 35}, {name: 'Charlie', age: 18}], {key: 'age', order: 'desc'})
{
  "results": [{
      "x": [{
          "age": 35,
          "name": "Bob"
        }, {
          "age": 25,
          "name": "Alice"
        }, {
          "age": 18,
          "name": "Charlie"
        }]
    }]
}
```

**collSortMulti**

```
collSortMulti(coll :: LIST OF MAP?, 
configs = [] :: LIST OF MAP, 
limit = -1 :: INTEGER?, 
skip = 0 :: INTEGER?) :: (LIST? OF ANY?)
```

 Renvoie une liste de cartes triées en fonction de la valeur des `key` propriétés spécifiées, en appliquant éventuellement une limite et un saut. 

```
RETURN collSortMulti([{name: 'Alice', age: 25}, {name: 'Bob', age: 35}, {name: 'Charlie', age: 18}], [{key: 'age', order: 'desc'}, {key:'name'}]) as x
{
  "results": [{
      "x": [{
          "age": 35,
          "name": "Bob"
        }, {
          "age": 25,
          "name": "Alice"
        }, {
          "age": 18,
          "name": "Charlie"
        }]
    }]
}
```

**collSortNodes**

 `collSortNodes(coll :: LIST OF NODE, config :: MAP) :: (LIST? OF NODE?)` 

 Renvoie une version triée de la liste `coll` d'entrée, triant les éléments du nœud en fonction des valeurs de leurs `key` propriétés respectives. 

```
create (n:person {name: 'Alice', age: 23}), (m:person {name: 'Eve', age: 21}), (o:person {name:'Bob', age:25})
{"results":[]}

match (n:person) with collect(n) as people return collSortNodes(people, {key: 'name', order: 'desc'})
{
  "results": [{
      "collSortNodes(people, 'name')": [{
          "~id": "e599240a-8c23-4337-8aa8-f603c8fb5488",
          "~entityType": "node",
          "~labels": ["person"],
          "~properties": {
            "age": 21,
            "name": "Eve"
          }
        }, {
          "~id": "8a6ef785-59e3-4a0b-a0ff-389655a9c4e6",
          "~entityType": "node",
          "~labels": ["person"],
          "~properties": {
            "age": 25,
            "name": "Bob"
          }
        }, {
          "~id": "466bc826-f47f-452c-8a27-6b7bdf7ae9b4",
          "~entityType": "node",
          "~labels": ["person"],
          "~properties": {
            "age": 23,
            "name": "Alice"
          }
        }]
    }]
}

match (n:person) with collect(n) as people return collSortNodes(people, {key: 'age'})
{
  "results": [{
      "collSortNodes(people, '^age')": [{
          "~id": "e599240a-8c23-4337-8aa8-f603c8fb5488",
          "~entityType": "node",
          "~labels": ["person"],
          "~properties": {
            "age": 21,
            "name": "Eve"
          }
        }, {
          "~id": "466bc826-f47f-452c-8a27-6b7bdf7ae9b4",
          "~entityType": "node",
          "~labels": ["person"],
          "~properties": {
            "age": 23,
            "name": "Alice"
          }
        }, {
          "~id": "8a6ef785-59e3-4a0b-a0ff-389655a9c4e6",
          "~entityType": "node",
          "~labels": ["person"],
          "~properties": {
            "age": 25,
            "name": "Bob"
          }
        }]
    }]
}
```

## Fonctions temporelles
<a name="temporal-functions"></a>

 Les fonctions temporelles sont disponibles à partir de Neptune [1.4.5.0](https://docs.aws.amazon.com/releases/release-1.4.5.0.xml). 

### day
<a name="temporal-functions-day"></a>

 `day(temporal :: (datetime | date)) :: (LONG)` 

 Renvoie le `day` mois à partir d'une `date` valeur `datetime` ou. Pour `datetime` : les valeurs sont normalisées en UTC en fonction des entrées avant d'extraire le jour. Pour `date` : le jour est extrait en fonction du fuseau horaire. 

 L'`datetime`entrée est disponible à la fois dans Neptune Database et Neptune Analytics : 

```
RETURN day(datetime('2021-06-03T01:48:14Z'))
{
  "results": [{
      "day(datetime('2021-06-03T01:48:14Z'))": 3
    }]
}
```

 Ici, le `datetime` temps est normalisé en UTC, donc \$1 08:00 revient au 2 juin. 

```
RETURN day(datetime('2021-06-03T00:00:00+08:00'))
{
  "results": [{
      "day(datetime('2021-06-03T00:00:00+08:00'))": 2
    }]
}
```

 L'`date`entrée n'est disponible que dans Neptune Analytics : 

```
RETURN day(date('2021-06-03Z'))
{
  "results": [{
      "day(date('2021-06-03Z'))": 3
    }]
}
```

 Le fuseau horaire `date` préserve, en gardant le 3 juin. 

```
RETURN day(date('2021-06-03+08:00'))
{
  "results": [{
      "day(date('2021-06-03+08:00'))": 3
    }]
}
```

### month
<a name="temporal-functions-month"></a>

 `month(temporal :: (datetime | date)) :: (LONG)` 

 Renvoie le mois à partir d'une `date` valeur `datetime` ou (1-12). Pour `datetime` : les valeurs sont normalisées en UTC en fonction des entrées avant d'extraire le mois. Pour `date` : le mois est extrait en fonction du fuseau horaire. 

 L'`datetime`entrée est disponible à la fois dans Neptune Database et Neptune Analytics : 

```
RETURN month(datetime('2021-06-03T01:48:14Z'))
{
  "results": [{
      "month(datetime('2021-06-03T01:48:14Z'))": 6
    }]
}
```

 Ici, le `datetime` temps est normalisé en UTC, donc \$1 08:00 revient au 31 mai. 

```
RETURN month(datetime('2021-06-01T00:00:00+08:00'))
{
  "results": [{
      "month(datetime('2021-06-01T00:00:00+08:00'))": 5
    }]
}
```

 L'`date`entrée n'est disponible que dans Neptune Analytics : 

```
RETURN month(date('2021-06-03Z'))
{
  "results": [{
      "month(date('2021-06-03Z'))": 6
    }]
}
```

 Le fuseau horaire `date` préserve, en gardant le 1er juin. 

```
RETURN month(date('2021-06-01+08:00'))
{
  "results": [{
      "month(date('2021-06-01+08:00'))": 6
    }]
}
```

### year
<a name="temporal-functions-year"></a>

 `year(temporal :: (datetime | date)) :: (LONG)` 

 Renvoie l'année à partir d'une `date` valeur `datetime` ou. Pour `datetime` : les valeurs sont normalisées en UTC sur la base des données saisies avant d'extraire l'année. Pour `date` : l'année est extraite en fonction du fuseau horaire. 

 L'`datetime`entrée est disponible à la fois dans Neptune Database et Neptune Analytics : 

```
RETURN year(datetime('2021-06-03T01:48:14Z'))
{
  "results": [{
      "year(datetime('2021-06-03T01:48:14Z'))": 2021
    }]
}
```

 Ici, le `datetime` temps est normalisé en UTC, donc \$1 08:00 revient au 31 décembre 2020. 

```
RETURN year(datetime('2021-01-01T00:00:00+08:00'))
{
  "results": [{
      "year(datetime('2021-01-01T00:00:00+08:00'))": 2020
    }]
}
```

 L'`date`entrée n'est disponible que dans Neptune Analytics : 

```
RETURN year(date('2021-06-03Z'))
{
  "results": [{
      "year(date('2021-06-03Z'))": 2021
    }]
}
```

 Le fuseau horaire `date` préserve le mois de juin 2021. 

```
RETURN year(date('2021-01-01+08:00'))
{
  "results": [{
      "year(date('2021-01-01+08:00'))": 2021
    }]
}
```

### Fonctions Neptune OpenCypher
<a name="openCypher-functions"></a>

 Disponible dans Neptune Database 1.4.6.0 et versions ultérieures, et dans Neptune Analytics. 

#### réduire ()
<a name="openCypher-functions-reduce"></a>

 Reduce traite séquentiellement chaque élément de la liste en le combinant avec un total cumulé ou un « accumulateur ». En commençant par une valeur initiale, il met à jour l'accumulateur après chaque opération et utilise cette valeur mise à jour lors de l'itération suivante. 

 `for i in (0, ..., n) acc = acc X list[I], where X denotes any binary operator` 

 Une fois que tous les éléments ont été traités, il renvoie le résultat final cumulé. 

 Une structure de réduction () typique serait - `reduce(accumulator = initial , variable IN list | expression)` 

**Spécifications du type :**  
 `- initial: starting value for the accumulator :: (Long | FLOAT | STRING | LIST? OF (STRING, LONG, FLOAT)) - list: the input list :: LIST OF T where T matches initial type - variable :: represents each element in the input list - expression :: Only supports '+' and '*' operator - return :: Same type as initial ` 

**Restrictions :**  
 Actuellement, l'`reduce()`expression ne prend en charge que : 
+  Multiplication numérique 
+  Addition numérique 
+  Concaténation de chaînes 
+  Concaténation de listes 

 Ils sont représentés par l'`*`opérateur `+` or. L'expression doit être une expression binaire comme indiqué ci-dessous - `expression pattern: accumulator + any variable or accumulator * any variable` 

**Gestion des débordements :**  
 Neptune détecte un dépassement numérique lors de l'`reduce()`évaluation et réagit différemment en fonction du type de données : 

```
LONG (signed 64‑bit)
--------------------
• Valid range: –9 223 372 036 854 775 808 … 9 223 372 036 854 775 807  
• If any intermediate or final value falls outside this range,
  Neptune aborts the query with long overflow error message.
  
FLOAT (IEEE‑754 double)
-----------------------
• Largest finite value ≈ 1.79 × 10^308  
• Larger results overflow to INF
  Once `INF` is produced, it propagates through the remainder
  of the reduction.
```

**Exemples :**  
Consultez les exemples suivants pour la fonction reduce ().

```
1. Long Addition:
RETURN reduce(sum = 0, n IN [1, 2, 3] | sum + n)
{
  "results": [{
      "reduce(sum = 0, n IN [1, 2, 3] | sum + n)": 6
    }]
}

2. String Concatenation:
RETURN reduce(str = "", x IN ["A", "B", "C"] | str + x) 
{
  "results": [{
      "reduce(str = "", x IN ["A", "B", "C"] | str + x)": "ABC"
    }]
}

3. List Combination:
RETURN reduce(lst = [], x IN [1, 2, 3] | lst + x)
{
  "results": [{
      "reduce(lst = [], x IN [1, 2, 3] | lst + x)": [1, 2, 3]
    }]
}

4. Float Addition:
RETURN reduce(total = 0.0, x IN [1.5, 2.5, 3.5] | total + x) 
{
  "results": [{
      "reduce(total = 0.0, x IN [1.5, 2.5, 3.5] | total + x)": 7.5
    }]
}

5. Long Multiplication:
RETURN reduce(product = 1, n IN [1, 2, 3] | product * n)
{
  "results": [{
      "reduce(product = 0, n IN [1, 2, 3] | product * n)": 6
    }]
}

6. Float Multiplication:
RETURN reduce(product = 1.0, n IN [1.5, 2.5, 3.5] | product * n)
{
  "results": [{
      "reduce(product = 1.0, n IN [1.5, 2.5, 3.5] | product * n)": 13.125
    }]
}

7. Long Overflow (Exception):
RETURN reduce(s = 9223372036854775807, x IN [2, 3] | s * x) AS result
{
"results": [{
    "reduce(s = 9223372036854775807, x IN [2, 3] | s * x) AS result": long overflow
    }]
}

8. Float Overflow:
RETURN reduce(s = 9.0e307, x IN [8.0e307, 1.0e307] | s + x) AS result
{
"results": [{
    "reduce(s = 9.0e307, x IN [8.0e307, 1.0e307] | s + x) AS result": INF
    }]
}
```

# neptune.read ()
<a name="access-graph-opencypher-21-extensions-s3-read"></a>

 Neptune prend en charge une `CALL` procédure `neptune.read` permettant de lire les données d'Amazon S3, puis d'exécuter une requête OpenCypher (lecture, insertion, mise à jour) à l'aide de ces données. La procédure génère chaque ligne du fichier en tant que ligne de variable de résultat déclarée. Il utilise les informations d'identification IAM de l'appelant pour accéder aux données dans Amazon S3. Consultez [Gérer les autorisations pour neptune.read ()](access-graph-opencypher-21-extensions-s3-read-permissions.md) pour configurer les autorisations. La AWS région du compartiment Amazon S3 doit se trouver dans la même région que celle où se trouve l'instance. Actuellement, les lectures entre régions ne sont pas prises en charge. 

 **Syntaxe** 

```
CALL neptune.read(
  {
    source: "string",
    format: "parquet/csv",
    concurrency: 10
  }
)
YIELD row
...
```

**Inputs**
+  **source** (obligatoire) - URI Amazon S3 vers un **seul** objet. Le préfixe Amazon S3 désignant plusieurs objets n'est pas pris en charge. 
+  **format** (obligatoire) - `parquet` et `csv` sont pris en charge. 
  +  Vous trouverez plus de détails sur le format Parquet pris en charge dans[Types de colonnes de parquet pris en charge](access-graph-opencypher-21-extensions-s3-read-parquet.md#access-graph-opencypher-21-extensions-s3-read-parquet-column-types). 
  +  Pour plus d'informations sur le format csv pris en charge, consultez[Format de chargement des données openCypher](bulk-load-tutorial-format-opencypher.md). 
+  **simultanéité** (facultatif) - Type : entier égal ou supérieur à 0. Valeur par défaut : 0. Spécifie le nombre de threads à utiliser pour lire le fichier. Si la valeur est 0, le nombre maximum de threads autorisés par la ressource sera utilisé. Pour le parquet, il est recommandé de définir un certain nombre de groupes de lignes. 

**Sorties**

 Le fichier neptune.read renvoie : 
+  **ligne** - Type : carte 
  +  Chaque ligne du fichier, où les clés sont les colonnes et les valeurs sont les données présentes dans chaque colonne. 
  +  Vous pouvez accéder aux données de chaque colonne sous la forme d'un accès aux propriétés (`row.col`). 

## Meilleures pratiques pour neptune.read ()
<a name="access-graph-opencypher-21-extensions-s3-read-best-practices"></a>

Les opérations de lecture de Neptune S3 peuvent être gourmandes en mémoire. Veuillez utiliser des types d'instance adaptés aux charges de travail de production, comme indiqué dans la section [Choix des types d'instance pour Amazon Neptune](instance-types.md).

L'utilisation de la mémoire et les performances des `neptune.read()` requêtes sont affectées par divers facteurs tels que la taille du fichier, le nombre de colonnes, le nombre de lignes et le format du fichier. Selon la structure, les petits fichiers (par exemple, les fichiers CSV de 100 Mo ou moins, les fichiers Parquet de 20 Mo ou moins) peuvent fonctionner de manière fiable sur la plupart des types d'instances adaptés à la production, tandis que les fichiers plus volumineux peuvent nécessiter une mémoire importante que les types d'instances plus petits ne peuvent pas fournir.

Lorsque vous testez cette fonctionnalité, il est recommandé de commencer par de petits fichiers et de procéder à une mise à l'échelle progressive afin de garantir que votre charge de travail de lecture puisse être adaptée à la taille de votre instance. Si vous remarquez que des `neptune.read()` demandes entraînent out-of-memory des exceptions ou des redémarrages d'instances, envisagez de diviser vos fichiers en plus petits morceaux, de réduire la complexité des fichiers ou de passer à des types d'instances plus importants.

# Exemples de requêtes utilisant du parquet
<a name="access-graph-opencypher-21-extensions-s3-read-parquet"></a>

L'exemple de requête suivant renvoie le nombre de lignes d'un fichier Parquet donné :

```
CALL neptune.read(
  {
    source: "<s3 path>",
    format: "parquet"
  }
)
YIELD row
RETURN count(row)
```

Vous pouvez exécuter l'exemple de requête à l'aide de l'`execute-open-cypher-query`opération décrite dans le en AWS CLI exécutant le code suivant :

```
aws neptunedata execute-open-cypher-query \
--open-cypher-query "CALL neptune.read({source: '<s3 path>', format: 'parquet'}) YIELD row RETURN count(row)" \
--endpoint-url https://my-cluster-name.cluster-abcdefgh1234.us-east-1.neptune.amazonaws.com:8182
```

Une requête peut être flexible quant à l'utilisation des lignes lues à partir d'un fichier Parquet. Par exemple, la requête suivante crée un nœud dont le champ est défini sur la base des données trouvées dans le fichier Parquet :

```
CALL neptune.read(
  {
    source: "<s3 path>",
    format: "parquet"
  }
)
YIELD row
CREATE (n {someField: row.someCol}) 
RETURN n
```

**Avertissement**  
Il n'est pas considéré comme une bonne pratique d'utiliser une clause volumineuse produisant des résultats comme `MATCH(n)` avant une `CALL` clause. Cela entraînerait une requête de longue durée, en raison d'un produit croisé entre les solutions entrantes issues des clauses précédentes et les lignes lues par neptune.read. Il est recommandé de démarrer la requête avec `CALL` neptune.read.

## Types de colonnes de parquet pris en charge
<a name="access-graph-opencypher-21-extensions-s3-read-parquet-column-types"></a>

**Types de données sur le parquet :**
+ NULL
+ BOOLEAN
+ FLOAT
+ DOUBLE
+ CHAÎNE
+ ENTIER SIGNÉ : UINT8, UINT16, UINT32, UINT64
+ MAP : ne prend en charge qu'un seul niveau. Ne prend pas en charge le mode imbriqué.
+ LISTE : ne prend en charge qu'un seul niveau. Ne prend pas en charge le mode imbriqué.

**Types de données spécifiques à Neptune :**

Contrairement aux en-têtes de colonne de propriétés au format CSV, les en-têtes de colonne de propriétés du format Parquet doivent uniquement contenir les noms des propriétés, il n'est donc pas nécessaire d'avoir les noms des types ni la cardinalité.

Certains types de colonnes spéciaux au format Parquet nécessitent toutefois une annotation dans les métadonnées, notamment le type Any, le type Date, le type DateTime et le type Geometry. L'objet suivant est un exemple de l'annotation de métadonnées requise pour les fichiers contenant des colonnes de ces types spéciaux :

```
"metadata": {
    "anyTypeColumns": ["UserCol1"],
    "dateTypeColumns": ["UserCol2"],
    "dateTimeTypeColumns": ["UserCol3"],
    "geometryTypeColumns": ["UserCol4"]
}
```

Vous trouverez ci-dessous des informations détaillées sur la charge utile attendue associée à ces types :
+ Un type de colonne Any est pris en charge dans les colonnes utilisateur. Un type quelconque est un « sucre syntaxique » pour tous les autres types que nous prenons en charge. C'est extrêmement utile si une colonne utilisateur contient plusieurs types. La charge utile d'une valeur de type Any est une liste de chaînes json comme suit :`{"value": "10", "type": "Int"};{"value": "1.0", "type": "Float"}`, qui contient un champ de valeur et un champ de type dans chaque chaîne json individuelle. La valeur de cardinalité d'une colonne Any est définie, ce qui signifie que la colonne peut accepter plusieurs valeurs. 
  + Neptune prend en charge les types suivants dans tous les types : Bool (ou Boolean), Byte, Short, Int, Long,,,,, Float UnsignedByte UnsignedShort, Double UnsignedInt, Date UnsignedLong, DateTime, String et Geometry.
  + Le type de vecteur n'est pris en charge dans aucun type.
  + Nested Tous les types ne sont pas pris en charge. Par exemple, `{"value": {"value": "10", "type": "Int"}, "type": "Any"}`.
+ Les colonnes de type Date et Datetime sont prises en charge dans les colonnes utilisateur. La charge utile de ces colonnes doit être fournie sous forme de chaînes suivant le format XSD ou l'un des formats ci-dessous : 
  + yyyy-MM-dd
  + YYYY-MM-DDTHH : mm
  + YYYY-MM-DDTHH : mm : SS
  + YYYY-MM-DDTHH : MM : SSZ
  + YYYY-MM-DDTHH:MM:SS.SSSZ
  + YYYY-MM-DDTHH:mm:SS [\$1\$1-] hhmm
  + YYYY-MM-DDTHH:MM:SSS [\$1\$1-] hhmm
+ Un type de colonne de géométrie est pris en charge dans les colonnes utilisateur. La charge utile de ces colonnes ne doit contenir que des primitives de géométrie de type Point, fournies sous forme de chaînes au format WKT (texte connu). Par exemple, POINT (30 10) serait une valeur de géométrie valide.

## Exemple de sortie pour parquet
<a name="sample-parquet-output"></a>

Étant donné un fichier Parquet comme celui-ci :

```
<s3 path>

Parquet Type:
    int8     int16       int32             int64              float      double    string
+--------+---------+-------------+----------------------+------------+------------+----------+
|   Byte |   Short |       Int   |                Long  |     Float  |    Double  | String   |
|--------+---------+-------------+----------------------+------------+------------+----------|
|   -128 |  -32768 | -2147483648 | -9223372036854775808 |    1.23456 |    1.23457 | first    |
|    127 |   32767 |  2147483647 |  9223372036854775807 |  nan       |  nan       | second   |
|      0 |       0 |           0 |                    0 | -inf       | -inf       | third    |
|      0 |       0 |           0 |                    0 |  inf       |  inf       | fourth   |
+--------+---------+-------------+----------------------+------------+------------+----------+
```

Voici un exemple de sortie renvoyée par neptune.read à l'aide de la requête suivante :

```
aws neptunedata execute-open-cypher-query \
--open-cypher-query "CALL neptune.read({source: '<s3 path>', format: 'parquet'}) YIELD row RETURN row" \
--endpoint-url https://my-cluster-name.cluster-abcdefgh1234.us-east-1.neptune.amazonaws.com:8182
```

```
{
 "results": [{
 "row": {
 "Float": 1.23456,
 "Byte": -128,
 "Int": -2147483648,
 "Long": -9223372036854775808,
 "String": "first",
 "Short": -32768,
 "Double": 1.2345678899999999
 }
 }, {
 "row": {
 "Float": "NaN",
 "Byte": 127,
 "Int": 2147483647,
 "Long": 9223372036854775807,
 "String": "second",
 "Short": 32767,
 "Double": "NaN"
 }
 }, {
 "row": {
 "Float": "-INF",
 "Byte": 0,
 "Int": 0,
 "Long": 0,
 "String": "third",
 "Short": 0,
 "Double": "-INF"
 }
 }, {
 "row": {
 "Float": "INF",
 "Byte": 0,
 "Int": 0,
 "Long": 0,
 "String": "fourth",
 "Short": 0,
 "Double": "INF"
 }
 }]
}
```

Il n'existe actuellement aucun moyen de définir une étiquette de nœud ou de bord pour un champ de données provenant d'un fichier Parquet. Il est recommandé de partitionner les requêtes en plusieurs requêtes, une pour chaque étiquette/type.

```
CALL neptune.read({source: '<s3 path>', format: 'parquet'})
 YIELD row 
WHERE row.`~label` = 'airport'
CREATE (n:airport)

CALL neptune.read({source: '<s3 path>', format: 'parquet'})
YIELD row 
WHERE row.`~label` = 'country'
CREATE (n:country)
```

# Exemples de requêtes à l'aide de CSV
<a name="access-graph-opencypher-21-extensions-s3-read-csv"></a>

Dans cet exemple, la requête renvoie le nombre de lignes d'un fichier CSV donné :

```
CALL neptune.read(
  {
    source: "<s3 path>",
    format: "csv"
  }
)
YIELD row
RETURN count(row)
```

Vous pouvez exécuter l'exemple de requête à l'aide de l' execute-open-cypher-queryopération décrite dans le en AWS CLI exécutant le code suivant :

```
aws neptunedata execute-open-cypher-query \
--open-cypher-query "CALL neptune.read({source: '<s3 path>', format: 'csv'}) YIELD row RETURN count(row)" \
--endpoint-url https://my-cluster-name.cluster-abcdefgh1234.us-east-1.neptune.amazonaws.com:8182
```

Une requête peut être flexible quant à l'utilisation des lignes lues à partir d'un fichier CSV. Par exemple, la requête suivante crée un nœud avec un champ défini sur les données d'un fichier CSV :

```
CALL neptune.read(
  {
    source: "<s3 path>",
    format: "csv"
  }
)
YIELD row
CREATE (n {someField: row.someCol}) 
RETURN n
```

**Avertissement**  
Il n'est pas considéré comme une bonne pratique d'utiliser une clause de grande taille produisant des résultats telle que MATCH (n) avant une clause CALL. Cela entraînerait une requête de longue durée en raison d'un produit croisé entre les solutions entrantes issues des clauses précédentes et les lignes lues par neptune.read. Il est recommandé de démarrer la requête avec CALL neptune.read.

## En-têtes de colonnes de propriétés
<a name="property-column-headers"></a>

Vous pouvez spécifier une colonne (`:`) pour une propriété à l'aide de la syntaxe suivante. Les noms de type ne sont pas sensibles à la casse. Si deux points apparaissent dans le nom d'une propriété, il faut l'éviter en le faisant précéder d'une barre oblique inverse :. `\:`

```
propertyname:type
```

**Note**  
Les espaces, les virgules, le retour en chariot et les caractères de nouvelle ligne ne sont pas autorisés dans les en-têtes de colonne. Les noms de propriétés ne peuvent donc pas inclure ces caractères.
Vous pouvez spécifier une colonne pour un type de tableau en ajoutant `[]` au type :  

  ```
                          propertyname:type[]
  ```
Les propriétés d'arc ne peuvent avoir qu'une seule valeur et provoquent une erreur si un type de tableau ou une seconde valeur est spécifié. L'exemple suivant montre l'en-tête de colonne d'une propriété nommée age de type Int :  

  ```
  age:Int
  ```

Chaque ligne du fichier doit obligatoirement avoir un nombre entier dans cette position ou rester vide. Les tableaux de chaînes sont autorisés, mais les chaînes d'un tableau ne peuvent pas inclure le point-virgule (`;`) à moins qu'il ne soit évité par une barre oblique inverse (). `\;`

## Types de colonnes CSV pris en charge
<a name="supported-csv-column-types"></a>
+ **BOOL (ou BOOLEAN)** - Valeurs autorisées : true, false. Indique un champ booléen. Toute valeur autre que true sera traitée comme fausse.
+ **FLOAT** - Plage : virgule flottante IEEE 754 32 bits, y compris Infinity, INF, -Infinity, -INF et NaN (). not-a-number
+ **DOUBLE** : plage : virgule flottante IEEE 754 64 bits, y compris Infinity, INF, -Infinity, -INF et NaN (). not-a-number
+ **CHAÎNE** - 
  + Les guillemets sont facultatifs. Les virgules, les nouvelles lignes et les caractères renvoyant le chariot sont automatiquement ignorés s'ils sont inclus dans une chaîne entourée de guillemets doubles («). Exemple : « Bonjour tout le monde ».
  + Pour inclure des guillemets dans une chaîne entre guillemets, vous pouvez éviter les guillemets en utilisant deux guillemets d'affilée : « Hello «" World" "».
  + Les tableaux de chaînes sont autorisés, mais les chaînes d'un tableau ne peuvent pas inclure le point-virgule (;) à moins qu'il ne soit évité par une barre oblique inverse (\$1 ;).
  + Si vous souhaitez placer des chaînes d'un tableau entre guillemets, vous devez entourer la totalité du tableau par un ensemble de guillemets. Exemple : « Chaîne 1 ; Chaîne 2 ; Chaîne 3 ».
+ **DATE, DATETIME** - Les valeurs de date/heure peuvent être fournies au format XSD ou dans l'un des formats suivants : 
  + yyyy-MM-dd
  + YYYY-MM-DDTHH : mm
  + YYYY-MM-DDTHH : mm : SS
  + YYYY-MM-DDTHH : MM : SSZ
  + YYYY-MM-DDTHH:MM:SS.SSSZ
  + YYYY-MM-DDTHH:mm:SS [\$1\$1-] hhmm
  + YYYY-MM-DDTHH:MM:SSS [\$1\$1-] hhmm
+ **ENTIER SIGNÉ** - 
  + Octet : -128 à 127
  + Court : -32768 à 32767
  + Int : -2^31 à 2^31-1
  + Longue : -2^63 à 2^63-1

**Types de colonnes spécifiques à Neptune :**
+ Un type de colonne Any est pris en charge dans les colonnes utilisateur. Un type quelconque est un « sucre syntaxique » pour tous les autres types que nous prenons en charge. C'est extrêmement utile si une colonne utilisateur contient plusieurs types. La charge utile d'une valeur de type Any est une liste de chaînes json comme suit :`{"value": "10", "type": "Int"};{"value": "1.0", "type": "Float"}`, qui contient un champ de valeur et un champ de type dans chaque chaîne json individuelle. L'en-tête de colonne d'un type Any est PropertyName:Any. La valeur de cardinalité d'une colonne Any est définie, ce qui signifie que la colonne peut accepter plusieurs valeurs. 
  + Neptune prend en charge les types suivants dans tous les types : Bool (ou Boolean), Byte, Short, Int, Long,,,,, Float UnsignedByte UnsignedShort, Double UnsignedInt, Date UnsignedLong, DateTime, String et Geometry.
  + Le type de vecteur n'est pris en charge dans aucun type.
  + Nested Tous les types ne sont pas pris en charge. Par exemple, `{"value": {"value": "10", "type": "Int"}, "type": "Any"}`.
+ Un type de colonne de géométrie est pris en charge dans les colonnes utilisateur. La charge utile de ces colonnes ne doit contenir que des primitives de géométrie de type Point, fournies sous forme de chaînes au format WKT (texte connu). Par exemple, POINT (30 10) serait une valeur de géométrie valide.

## Exemple de sortie CSV
<a name="sample-csv-output"></a>

Compte tenu du fichier CSV suivant :

```
<s3 path>
colA:byte,colB:short,colC:int,colD:long,colE:float,colF:double,colG:string
-128,-32768,-2147483648,-9223372036854775808,1.23456,1.23457,first
127,32767,2147483647,9223372036854775807,nan,nan,second
0,0,0,0,-inf,-inf,third
0,0,0,0,inf,inf,fourth
```

Cet exemple montre le résultat renvoyé par neptune.read à l'aide de la requête suivante :

```
aws neptunedata execute-open-cypher-query \
--open-cypher-query "CALL neptune.read({source: '<s3 path>', format: 'csv'}) YIELD row RETURN row" \
--endpoint-url https://my-cluster-name.cluster-abcdefgh1234.us-east-1.neptune.amazonaws.com:8182
```

```
{
  "results": [{
      "row": {
        "colD": -9223372036854775808,
        "colC": -2147483648,
        "colE": 1.23456,
        "colB": -32768,
        "colF": 1.2345699999999999,
        "colG": "first",
        "colA": -128
      }
    }, {
      "row": {
        "colD": 9223372036854775807,
        "colC": 2147483647,
        "colE": "NaN",
        "colB": 32767,
        "colF": "NaN",
        "colG": "second",
        "colA": 127
      }
    }, {
      "row": {
        "colD": 0,
        "colC": 0,
        "colE": "-INF",
        "colB": 0,
        "colF": "-INF",
        "colG": "third",
        "colA": 0
      }
    }, {
      "row": {
        "colD": 0,
        "colC": 0,
        "colE": "INF",
        "colB": 0,
        "colF": "INF",
        "colG": "fourth",
        "colA": 0
      }
    }]
}
```

Il n'existe actuellement aucun moyen de définir une étiquette de nœud ou de bordure pour un champ de données provenant d'un fichier CSV. Il est recommandé de partitionner les requêtes en plusieurs requêtes, une pour chaque étiquette/type.

```
CALL neptune.read({source: '<s3 path>', format: 'csv'})
 YIELD row 
WHERE row.`~label` = 'airport'
CREATE (n:airport)

CALL neptune.read({source: '<s3 path>', format: 'csv'})
YIELD row 
WHERE row.`~label` = 'country'
CREATE (n:country)
```

# Gérer les autorisations pour neptune.read ()
<a name="access-graph-opencypher-21-extensions-s3-read-permissions"></a>

## Politiques IAM requises
<a name="access-graph-opencypher-21-extensions-s3-read-permissions-iam"></a>

Pour exécuter les requêtes OpenCypher utilisées`neptune.read()`, vous devez disposer des autorisations appropriées pour accéder aux données de votre base de données Neptune. Les requêtes en lecture seule nécessitent cette action. `ReadDataViaQuery` Les requêtes qui modifient les données nécessitent `WriteDataViaQuery` des insertions ou `DeleteDataViaQuery` des suppressions. L'exemple ci-dessous autorise les trois actions sur le cluster spécifié.

En outre, vous devez disposer d'autorisations pour accéder au compartiment S3 contenant vos fichiers de données. La déclaration de politique de Neptunes3Access accorde les autorisations S3 requises :
+ **`s3:ListBucket`**: obligatoire pour vérifier l'existence du bucket et le contenu de la liste.
+ **`s3:GetObject`**: Nécessaire pour accéder à l'objet spécifié afin que son contenu puisse être lu en vue de son intégration dans les requêtes OpenCypher.

Si votre compartiment S3 utilise le chiffrement côté serveur avec AWS KMS, vous devez également accorder des autorisations KMS. La KMSAccess déclaration de politique de Neptunes3 permet à Neptune de déchiffrer les données et de générer des clés de données lors de l'accès à des objets S3 chiffrés. Cette condition limite les opérations KMS aux demandes provenant des services S3 et RDS de votre région.
+ **`kms:Decrypt`**: Nécessaire pour effectuer le déchiffrement de l'objet chiffré afin que ses données puissent être lues par Neptune.
+ **`kms:GenerateDataKey`**: également requis par l'API S3 utilisée pour récupérer les objets à lire.

```
{
  "Sid": "NeptuneQueryAccess",
  "Effect": "Allow",
  "Action": [
      "neptune-db:ReadDataViaQuery",
      "neptune-db:WriteDataViaQuery",
      "neptune-db:DeleteDataViaQuery"
  ],
  "Resource": "arn:aws:neptune-db:<REGION>:<AWS_ACCOUNT_ID>:<CLUSTER_RESOURCE_ID>/*"
},
{
  "Sid": "NeptuneS3Access",
  "Effect": "Allow",
  "Action": [
      "s3:ListBucket",
      "s3:GetObject"
  ],
  "Resource": [
      "arn:aws:s3:::neptune-read-bucket",
      "arn:aws:s3:::neptune-read-bucket/*"
  ]
},
{
  "Sid": "NeptuneS3KMSAccess",
  "Effect": "Allow",
  "Action": [
      "kms:Decrypt",
      "kms:GenerateDataKey"
  ],
  "Resource": "arn:aws:kms:<REGION>:<AWS_ACCOUNT_ID>:key/<KEY_ID>",
  "Condition": {
      "StringEquals": {
        "kms:ViaService": [
            "s3.<REGION>.amazonaws.com",
            "rds.<REGION>.amazonaws.com"
        ]
      }
  }
}
```

## Conditions préalables importantes
<a name="access-graph-opencypher-21-extensions-s3-read-permissions-prerequisites"></a>

Ces autorisations et conditions préalables garantissent une intégration sûre et fiable des données S3 dans les requêtes OpenCypher, tout en maintenant des contrôles d'accès et des mesures de protection des données appropriés.
+ **Authentification IAM** : cette fonctionnalité n'est prise en charge que pour les clusters Neptune avec l'authentification IAM activée. Consultez [Sécurisation de votre base de données Amazon Neptune](security.md) pour obtenir des instructions détaillées sur la création et la connexion à des clusters compatibles avec l'authentification IAM.
+ **Point de terminaison VPC** :
  + Un point de terminaison VPC de type Gateway pour Amazon S3 est nécessaire pour permettre à Neptune de communiquer avec Amazon S3.
  + Pour utiliser un AWS KMS chiffrement personnalisé dans la requête, un point de terminaison VPC de type interface est requis AWS KMS pour permettre à Neptune de communiquer avec. AWS KMS
  + Pour obtenir des instructions détaillées sur la configuration de ce point de terminaison, consultez [Création du point de terminaison Amazon S3 VPC.](bulk-load-tutorial-IAM.md)