Импорт json в neo4J - PullRequest
0 голосов
/ 27 апреля 2020

Я бы хотел импортировать файл json, содержащий мои данные, в Neo4J. Однако он очень медленный.

Файл Json структурирован следующим образом:

{
    "graph": {
        "nodes": [
            { "id": 3510982, "labels": ["XXX"], "properties": { ... } },
            { "id": 3510983, "labels": ["XYY"], "properties": { ... } },
            { "id": 3510984, "labels": ["XZZ"], "properties": { ... } },
     ...
        ],
        "relationships": [
            { "type": "bla", "startNode": 3510983, "endNode": 3510982, "properties": {} },
            { "type": "bla", "startNode": 3510984, "endNode": 3510982, "properties": {} },
    ....
        ]
    }
}

Это похоже на предложенный здесь: Как восстановить данные из предыдущий результат в браузере? .

Глядя на ответ. Я обнаружил, что могу использовать

CALL apoc.load.json("file:///test.json") YIELD value AS row
WITH row, row.graph.nodes AS nodes
UNWIND nodes AS node
CALL apoc.create.node(node.labels, node.properties) YIELD node AS n
SET n.id = node.id

, а затем

CALL apoc.load.json("file:///test.json") YIELD value AS row
with row
UNWIND row.graph.relationships AS rel
MATCH (a) WHERE a.id = rel.endNode
MATCH (b) WHERE b.id = rel.startNode
CALL apoc.create.relationship(a, rel.type, rel.properties, b) YIELD rel AS r
return *

(я должен сделать это два раза, потому что в противном случае они являются дублированием отношений из-за двух unwind).

Но это очень медленно, потому что у меня много сущностей, и я подозреваю, что программа ищет их по всем отношениям.

В то же время я знаю, что "startNode": 3510983 относится в узел. Поэтому вопрос: существует ли он в любом случае для ускорения процесса импорта с использованием идентификаторов в качестве индекса или чего-то еще?

Обратите внимание, что мои узлы имеют разные типы. Поэтому я не нашел способ создать индекс для всех из них, и я полагаю, что он будет слишком большим (память)

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

[EDITED]

Этот подход может работает более эффективно:

CALL apoc.load.json("file:///test.json") YIELD value
WITH value.graph.nodes AS nodes, value.graph.relationships AS rels
UNWIND nodes AS n
CALL apoc.create.node(n.labels, apoc.map.setKey(n.properties, 'id', n.id)) YIELD node
WITH rels, apoc.map.mergeList(COLLECT({id: n.id, node: node})) AS nMap
UNWIND rels AS r
CALL apoc.create.relationship(nMap[r.startNode], r.type, r.properties, nMap[r.endNode]) YIELD rel
RETURN rel

Этот запрос вообще не использует MATCH (и не требует индексации) ), поскольку он просто полагается на отображение в памяти от импортированных идентификаторов узлов к созданным узлам. Однако этот запрос может исчерпать память, если имеется много импортированных узлов.

Он также позволяет избежать вызова SET с помощью apo c .map.setKey. для добавления свойства id к n.properties.

2 UNWIND s не вызывают декартово произведение, поскольку в этом запросе используется агрегирующая функция COLLECT (перед вторым UNWIND), чтобы сжать все предыдущие строки в один (потому что ключ группировки, rels, является одиночным).

0 голосов
/ 28 апреля 2020

Вы пробовали индексировать узлы до ЗАГРУЗКИ JSON? Это может быть недопустимым, так как у вас есть несколько меток узлов. Но если они ограничены, вы можете создать заполнитель узла, создать и проиндексировать, а затем удалить заполнитель. После этого запустите LOAD Json

    Create (n:YourLabel{indx:'xxx'})
    create index on: YourLabel(indx)
    match (n:YourLabel) delete n

Индекс ускорит сопоставление или объединение

...