запрос cypher в py2neo для обновления n узлов со списком n идентификаторов и параметров - PullRequest
0 голосов
/ 27 ноября 2018

Скажем, я хочу обновить значительное количество уже существующих узлов, используя данные, которые, например, хранятся в pd.Dataframe.Поскольку я знаю, как написать параметризованный запрос, который будет обрабатывать обновление одного узла, мое основное решение состоит в том, чтобы установить этот запрос в цикле и запускать его для каждой строки во фрейме данных.

for _,row in df.iterrows():
    query='''MATCH (p:Person)
             WHERE p.name={name} AND p.surname = {surname}
             SET p.description={description} '''


    tx.run(query,name=row['name'],surname=row['surname'],
           description=row['description'])

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

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Вместо того, чтобы зацикливаться, как это, с одним запросом Cypher, выполняемым для каждой записи, вы должны собрать все это в параметре списка объектов карты и сделать один запрос Cypher (вы можете пакетировать это, хотя, если у вас есть> 100k или около того записей дляпроцесс).У Майкла Хангера есть хорошая запись в блоге об этом подходе .

Вы можете использовать UNWIND в параметре списка, чтобы преобразовать его в строки и обрабатывать все сразу.Предполагая, что вы передаете в списке как data:

UNWIND $data as row
MATCH (p:Person)
WHERE p.name = row.name AND p.surname = row.surname
SET p.description = row.description
0 голосов
/ 28 ноября 2018

Существенная проблема уже решена в ответе InverseFalcon, но для предоставления полного ответа, включая py2neo и pandas bits, я выкладываю следующий код:

query='''UNWIND {batch} AS row
         MATCH (p:Person)
         WHERE p.name=row.name AND p.surname = row.surname
         SET p.description=row.description '''

graph.run(query,batch=df.to_dict(orient='records'))

Итак, наВ конце концов, это был скорее вопрос neo4j, чем py2neo, и соответствующая информация в документах neo4j: здесь

0 голосов
/ 27 ноября 2018

Вы можете сделать это, запустив запрос шифра LOAD и предоставив файл csv, содержащий ваши данные:

LOAD CSV WITH HEADERS FROM 'file:///file.csv' as csvLine fieldterminator ';' 
MATCH (p:Person {name:csvLine.name, p.surname:csvLine.surname})
SET p.description=csvLine.description

Но я не думаю, что существует решение для передачи массиваданных в цикл сопоставления.

...