

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Umschreiben von Cypher-Abfragen zur Ausführung in openCypher auf Neptune
<a name="migration-opencypher-rewrites"></a>

openCypher ist eine deklarative Abfragesprache für Eigenschaftsdiagramme. Ursprünglich von Neo4j entwickelt, wurde sie 2015 als Open-Source-Software veröffentlicht und ist unter einer Apache-2-Open-Source-Lizenz für das [openCypher](https://www.opencypher.org/)-Projekt verfügbar. Wir bei glauben AWS, dass Open Source für alle gut ist, und wir setzen uns dafür ein, unseren Kunden den Wert von Open Source und den Open-Source-Communities die operative Exzellenz AWS zu bieten.

OpenCypher Die Syntax ist in der [Cypher Query Language Reference, Version 9,](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf) dokumentiert.

Da OpenCypher eine Teilmenge der Syntax und Features der Cypher-Abfragesprache enthält, erfordern einige Migrationsszenarien entweder das Umschreiben von Abfragen in mit OpenCypher kompatible Form oder die Prüfung alternativer Methoden, um die gewünschte Funktionalität zu erreichen.

Dieser Abschnitt enthält Empfehlungen zum Umgang mit häufigen Unterschieden, die jedoch keineswegs erschöpfend sind. Sie sollten jede Anwendung, die diese Umschreibungen verwendet, gründlich testen, um sicherzustellen, dass die Ergebnisse Ihren Erwartungen entsprechen.

## Umschreiben von `None`-, `All`- und `Any`-Prädikatfunktionen
<a name="migration-opencypher-rewrites-none-all-any"></a>

Diese Funktionen sind nicht Teil der openCypher-Spezifikation. Vergleichbare Ergebnisse können mit List Comprehension in openCypher erzielt werden.

Finden Sie zum Beispiel alle Pfade, die von Knoten `Start` zu Knoten `End` führen, wobei aber kein Pfad einen Knoten passieren darf, dessen Klasseneigenschaft `D` ist:

```
# Neo4J Cypher code
match p=(a:Start)-[:HOP*1..]->(z:End)
where none(node IN nodes(p) where node.class ='D')
return p

# Neptune openCypher code
match p=(a:Start)-[:HOP*1..]->(z:End)
where size([node IN nodes(p) where node.class = 'D']) = 0
return p
```

List Comprehension kann diese Ergebnisse können wie folgt erreichen:

```
all  => size(list_comprehension(list)) = size(list)
any  => size(list_comprehension(list)) >= 1
none => size(list_comprehension(list)) = 0
```

## Umschreiben der Cypher-Funktion `reduce()` zu openCypher
<a name="migration-opencypher-rewrites-reduce"></a>

Die `reduce()`-Funktion ist nicht Teil der openCypher-Spezifikation. Sie wird häufig verwendet, um eine Aggregierung von Daten aus Elementen innerhalb einer Liste zu erstellen. In vielen Fällen können Sie eine Kombination aus List Comprehension und der `UNWIND`-Klausel verwenden, um ähnliche Ergebnisse zu erreichen.

Die folgende Cypher-Abfrage findet beispielsweise alle Flughäfen auf Wegen mit einer bis drei Stopps zwischen Anchorage (ANC) und Austin (AUS) und gibt die Gesamtentfernung für jeden Pfad zurück:

```
MATCH p=(a:airport {code: 'ANC'})-[r:route*1..3]->(z:airport {code: 'AUS'})
RETURN p, reduce(totalDist=0, r in relationships(p) | totalDist + r.dist) AS totalDist
ORDER BY totalDist LIMIT 5
```

Sie können dieselbe Abfrage in openCypher für Neptune wie folgt schreiben:

```
MATCH p=(a:airport {code: 'ANC'})-[r:route*1..3]->(z:airport {code: 'AUS'})
UNWIND [i in relationships(p) | i.dist] AS di
RETURN p, sum(di) AS totalDist
ORDER BY totalDist
LIMIT 5
```

## Umschreiben der Cypher-Klausel FOREACH zu openCypher
<a name="migration-opencypher-rewrites-foreach"></a>

Die FOREACH–Klausel ist nicht Teil der openCypher-Spezifikation. Sie wird häufig verwendet, um Daten während einer Abfrage zu aktualisieren, oft anhand von Aggregierungen oder Elementen innerhalb eines Pfads.

Finden Sie als Beispiel für einen Pfad nach allen Flughäfen auf einem Pfad mit nicht mehr als zwei Stopps zwischen Anchorage (ANC) und Austin (AUS) und legen Sie für jeden von ihnen die Eigenschaft „besucht“ fest:

```
# Neo4J Example
MATCH p=(:airport {code: 'ANC'})-[*1..2]->({code: 'AUS'})
FOREACH (n IN nodes(p) | SET n.visited = true)

# Neptune openCypher
MATCH p=(:airport {code: 'ANC'})-[*1..2]->({code: 'AUS'})
WITH nodes(p) as airports
UNWIND airports as a
SET a.visited=true
```

Ein weiteres Beispiel ist:

```
# Neo4J Example
MATCH p=(start)-[*]->(finish)
WHERE start.name = 'A' AND finish.name = 'D'
FOREACH (n IN nodes(p) | SET n.marked = true)

# Neptune openCypher
MATCH p=(start)-[*]->(finish)
WHERE start.name = 'A' AND finish.name = 'D'
UNWIND nodes(p) AS n
SET n.marked = true
```

## Umschreiben der Neo4j-APOC-Prozeduren zu Neptune
<a name="migration-opencypher-rewrites-apoc"></a>

In den folgenden Beispielen wird openCypher verwendet, um einige der am häufigsten verwendeten [APOC-Prozeduren](https://neo4j.com/blog/intro-user-defined-procedures-apoc/) zu ersetzen. Diese Beispiele dienen nur als Referenz und sollen einige Vorschläge zum Umgang mit gängigen Szenarien geben. In der Praxis ist jede Anwendung anders und Sie müssen Ihre eigenen Strategien entwickeln, um alle Funktionen bereitzustellen, die Sie benötigen.

### Umschreiben von `apoc.export`-Verfahren
<a name="migration-opencypher-rewrites-apoc-export"></a>

Neptune bietet mithilfe des [Neptune-Export](https://github.com/aws/neptune-export)-Dienstprogramms eine Reihe von Optionen sowohl für vollständige Graph- als auch für abfragebasierte Exporte in verschiedenen Ausgabeformaten wie CSV und JSON (siehe [Exportieren von Daten aus einem Neptune-DB-Cluster](neptune-data-export.md)).

### Umschreiben von `apoc.schema`-Verfahren
<a name="migration-opencypher-rewrites-apoc-schema"></a>

Neptune hat kein explizit definiertes Schema, keine Indizes oder Einschränkungen, so dass viele `apoc.schema`-Prozeduren nicht mehr erforderlich sind. Beispiele sind:
+ `apoc.schema.assert`
+ `apoc.schema.node.constraintExists`
+ `apoc.schema.node.indexExists`,
+ `apoc.schema.relationship.constraintExists`
+ `apoc.schema.relationship.indexExists`
+ `apoc.schema.nodes`
+ `apoc.schema.relationships`

Neptune openCypher unterstützt das Abrufen ähnlicher Werte wie die Prozeduren, wie unten gezeigt, kann jedoch bei größeren Graphen zu Leistungsproblemen führen, da dafür ein großer Teil des Graphen gescannt werden muss, um die Antwort zurückzugeben.

```
# openCypher replacement for apoc.schema.properties.distinct
MATCH (n:airport)
RETURN DISTINCT n.runways
```

```
# openCypher replacement for apoc.schema.properties.distinctCount
MATCH (n:airport)
RETURN DISTINCT n.runways, count(n.runways)
```

### Alternativen zu `apoc.do`-Prozeduren
<a name="migration-opencypher-rewrites-apoc-do"></a>

Diese Prozeduren werden verwendet, um eine bedingte Abfrageausführung zu ermöglichen, die mit anderen OpenCypher-Klauseln einfach zu implementieren ist. In Neptune gibt es mindestens zwei Möglichkeiten, ein ähnliches Verhalten zu erreichen:
+ Eine Möglichkeit besteht darin, die Listenverständnisfunktionen von OpenCypher mit der `UNWIND`-Klausel zu kombinieren.
+ Eine andere Möglichkeit besteht darin, die Schritte choose() und coalesce() in Gremlin zu verwenden.

Beispiele für diese Vorgehensweisen sind unten aufgeführt.

#### Alternativen zu apoc.do.when
<a name="migration-opencypher-rewrites-apoc-do-when"></a>

```
# Neo4J Example
MATCH (n:airport {region: 'US-AK'})
CALL apoc.do.when(
 n.runways>=3,
 'SET n.is_large_airport=true RETURN n',
 'SET n.is_large_airport=false RETURN n',
 {n:n}
) YIELD value
WITH collect(value.n) as airports
RETURN size([a in airports where a.is_large_airport]) as large_airport_count,
size([a in airports where NOT a.is_large_airport]) as small_airport_count


# Neptune openCypher
MATCH (n:airport {region: 'US-AK'})
WITH n.region as region, collect(n) as airports
WITH [a IN airports where a.runways >= 3] as large_airports,
[a IN airports where a.runways < 3] as small_airports, airports
UNWIND large_airports as la
SET la.is_large_airport=true
WITH DISTINCT small_airports, airports
UNWIND small_airports as la
    SET la.small_airports=true
WITH DISTINCT airports
RETURN size([a in airports where a.is_large_airport]) as large_airport_count,
size([a in airports where NOT a.is_large_airport]) as small_airport_count

#Neptune Gremlin using choose()
g.V().
  has('airport', 'region', 'US-AK').
  choose(
    values('runways').is(lt(3)),
    property(single, 'is_large_airport', false),
    property(single, 'is_large_airport', true)).
  fold().
  project('large_airport_count', 'small_airport_count').
    by(unfold().has('is_large_airport', true).count()).
    by(unfold().has('is_large_airport', false).count())

 #Neptune Gremlin using coalesce() 
g.V().
  has('airport', 'region', 'US-AK').
  coalesce(
    where(values('runways').is(lt(3))).
    property(single, 'is_large_airport', false),
    property(single, 'is_large_airport', true)).
  fold().
  project('large_airport_count', 'small_airport_count').
    by(unfold().has('is_large_airport', true).count()).
    by(unfold().has('is_large_airport', false).count())
```

#### Alternativen zu apoc.do.when
<a name="migration-opencypher-rewrites-apoc-do-case"></a>

```
# Neo4J Example
MATCH (n:airport {region: 'US-AK'})
CALL apoc.case([
 n.runways=1, 'RETURN "Has one runway" as b',
 n.runways=2, 'RETURN "Has two runways" as b'
 ],
 'RETURN "Has more than 2 runways" as b'
) YIELD value 
RETURN {type: value.b,airport: n}

# Neptune openCypher
MATCH (n:airport {region: 'US-AK'})
WITH n.region as region, collect(n) as airports
WITH [a IN airports where a.runways =1] as single_runway,
[a IN airports where a.runways =2] as double_runway,
[a IN airports where a.runways >2] as many_runway
UNWIND single_runway as sr
    WITH {type: "Has one runway",airport: sr} as res, double_runway, many_runway
WITH DISTINCT double_runway as double_runway, collect(res) as res, many_runway
UNWIND double_runway as dr
    WITH {type: "Has two runways",airport: dr} as two_runways, res, many_runway
WITH collect(two_runways)+res as res, many_runway
UNWIND many_runway as mr
    WITH {type: "Has more than 2 runways",airport: mr} as res2, res, many_runway
WITH collect(res2)+res as res
UNWIND res as r
RETURN r

#Neptune Gremlin using choose()
g.V().
  has('airport', 'region', 'US-AK').
  project('type', 'airport').
    by(
      choose(values('runways')).
        option(1, constant("Has one runway")).
        option(2, constant("Has two runways")).
        option(none, constant("Has more than 2 runways"))).
    by(elementMap())

 #Neptune Gremlin using coalesce()
 g.V().
  has('airport', 'region', 'US-AK').
  project('type', 'airport').
    by(
      coalesce(
        has('runways', 1).constant("Has one runway"),
        has('runways', 2).constant("Has two runways"),
        constant("Has more than 2 runways"))).
    by(elementMap())
```

## Alternativen zu listenbasierten Eigenschaften
<a name="migration-opencypher-rewrites-lists"></a>

Neptune unterstützt derzeit nicht das Speichern von auf Listen basierenden Eigenschaften. Ähnliche Ergebnisse können jedoch erzielt werden, wenn Listenwerte als kommagetrennte Zeichenfolge gespeichert und dann die Listeneigenschaft mithilfe der Funktionen `join()` und `split()` konstruiert und dekonstruiert wird.

Wenn wir beispielsweise eine Liste von Tags als Eigenschaft speichern möchten, könnten wir die Beispiel-Umschreibung verwenden, die zeigt, wie eine durch Kommata getrennte Eigenschaft abgerufen wird, und dann die Funktionen `split()` und `join()` mit List Comprehension verwenden, um vergleichbare Ergebnisse zu erzielen:

```
# Neo4j Example (In this example, tags is a durable list of string.
MATCH (person:person {name: "TeeMan"})
WITH person, [tag in person.tags WHERE NOT (tag IN ['test1', 'test2', 'test3'])] AS newTags
SET person.tags = newTags
RETURN person

# Neptune openCypher 
MATCH (person:person {name: "TeeMan"})
WITH person, [tag in split(person.tags, ',') WHERE NOT (tag IN ['test1', 'test2', 'test3'])] AS newTags
SET person.tags = join(newTags,',')
RETURN person
```

## CALL-Unterabfragen umschreiben
<a name="migration-opencypher-rewrites-call-subqueries"></a>

 `CALL`Neptune-Unterabfragen unterstützen die Syntax `CALL (friend) { ... }` für den Import von Variablen in den Unterabfragebereich nicht (in diesem `friend` Beispiel). Bitte verwenden Sie die `WITH` Klausel innerhalb der Unterabfrage für dasselbe, z. B. `CALL { WITH friend ... }` 

 Optionale `CALL` Unterabfragen werden derzeit nicht unterstützt. 

## Weitere Unterschiede zwischen Neptune openCypher und Cypher
<a name="opencypher-compliance-other-differences"></a>
+ Neptune unterstützt nur TCP-Verbindungen für das Bolt-Protokoll. WebSocketsVerbindungen für Bolt werden nicht unterstützt.
+ Neptune openCypher entfernt Leerzeichen in den Funktionen `trim()`, `ltrim()` und `rtrim()`, wie in Unicode definiert.
+ In Neptune openCypher wechselt `tostring(`double`)` bei großen Double-Werten nicht automatisch zur E-Notation.