Neo4j не может связать уже существующие узлы внутри FOREACH - PullRequest
0 голосов
/ 06 июля 2018

Я загружаю набор шахматных данных, где внутри строки напечатан «снимок» шахматной доски (FEN). Сначала я использую слияние на FEN, чтобы получить все уникальные позиции следующим образом:

LOAD CSV WITH HEADERS FROM 'file:///xxx/test.csv' AS LINE
FIELDTERMINATOR ';'
MERGE (p:Position { FEN:LINE.FEN })

Переходя от FEN к FEN, я хочу запечатлеть некоторые детали, касающиеся ходов игрока, а также игры. Но для этого мне нужно сначала упорядочить данные на основе игры и moveNumber. Это мой шифр:

LOAD CSV WITH HEADERS FROM 'file:///xxx/test.csv' AS LINE
FIELDTERMINATOR ';'
WITH LINE.FEN as FEN,LINE.GameNumber as gn,LINE.MoveNumber as mn,LINE.Side as side,LINE.Move as move
order by gn,mn
WITH COLLECT({FEN:FEN,gID:gn,moveNumber:mn,Side:side,Move:move}) as col
FOREACH(i in RANGE(0, length(col)-2)|
  FOREACH(ps1 in [col[i]] | 
    FOREACH(ps2 in [col[i+1]] |
        FOREACH (ignore in CASE
          WHEN ps1.gID = ps2.gID THEN [1]
          ELSE [] END |
            CREATE UNIQUE (pos1: Position{FEN: ps1.FEN})-[:MOVE{gID:ps2.gID,moveNumber:ps2.moveNumber,Side:ps2.Side,Move:ps2.Move}]->(pos2: Position{FEN: ps2.FEN})
      ))))

Ответ, который я получаю, - Unbound Pattern !, что я перевожу как «neo4j не может связать pos1 и pos2 в каждом случае».

Чтобы проверить это, я использовал MERGE и CREATE вместо CREATE UNIQUE, и оба по какой-то причине воссоздали все узлы Position. Хуже того, для каждого gID воссоздается весь шаблон вместо отдельной цепочки, как на этом изображении (воссозданные узлы и шаблоны) .

Я был бы очень признателен, если бы кто-то мог указать мне, почему это происходит, или предложить мне альтернативный подход. Я использую neo4j 2.3.5.

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

CREATE UNIQUE является устаревшим и поддерживается только устаревшим Cypher "Rule Planner". Возможно, в старом планировщике правил есть ошибки, вызывающие вашу проблему.

Следующий запрос расширяет подход, обозначенный @InverseFalcon (заменив CREATE UNIQUE на 3 MERGE s), и упрощает структуру запроса, устраняя все циклы FOREACH.

LOAD CSV WITH HEADERS FROM 'file:///xxx/test.csv' AS LINE FIELDTERMINATOR ';'
WITH LINE
ORDER BY LINE.GameNumber, LINE.MoveNumber
WITH COLLECT({FEN: LINE.FEN, gID: LINE.GameNumber, mn: LINE.MoveNumber, Side: LINE.Side, Move: LINE.Move}) as col
UNWIND [i IN RANGE(0, SIZE(col)-2) WHERE col[i].gID = col[i+1].gID | {p1: col[i], p2: col[i+1]}] AS x
MERGE (pos1: Position {FEN: x.p1.FEN})
MERGE (pos2: Position {FEN: x.p2.FEN})
MERGE (pos1)-[m:MOVE {gID: x.p2.gID, moveNumber: x.p2.mn}]->(pos2)
ON CREATE SET m.Side = x.p2.Side, m.Move = x.p2.Move;

В этом запросе я также предполагаю, что свойств gId и moveNumber достаточно для определения уникального отношения MOVE между одной и той же парой позиций.

0 голосов
/ 06 июля 2018

Попробуйте использовать 3 MERGE вместо одного CREATE UNIQUE.

MERGE pos1, затем MERGE pos2, затем MERGE отношения между ними.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...