2016-03-27 4 views
0

Скажем, у меня довольно большой объект JSON. Этот объект может быть вложен множеством способов и включать массивы. Объект дает мне пользователя и их отношение к уникальным объектам типа и нескольким (массивным) объектам типа.Cypher Insert Querying Neo4J

Моя цель - вставить это в Neo4j как можно быстрее и эффективнее.

Можно ли это сделать, и рекомендуется ли в одном запросе, который является конкатенированной строкой, созданной путем итерации структуры JSON? (Разбор объекта и абстрагирование на несколько узлов и отношений)

Также распространенная проблема, которая усложняет этот процесс: Для массивов, которые я выполняю, когда я объединяю утверждения MERGE, узлы в Neo4J получают дублируется, и слияние не работает.

//Person to interests 
_.each(interests, function(itr){ 
    ingestQuery += 'MERGE(centerRep)-[:INTERESTED_IN]->(:Interest{name: "'+itr.interest_name+'", category: "'+itr.interest_category+'"})' 
},this) 

Таким образом, если это утверждение выполняется дважды, узел интереса будет создан дважды, что является нежелательным поведением.

+0

«Это можно сделать, и это необходимо сделать в одном запросе, который является конкатенированной строкой, созданной путем итерации структуры JSON?» «Не уверен, что вы спрашиваете: вы хотите сохранить большую строку в Neo4j? Вы хотите проанализировать строку в формате JSON на несколько узлов? Вы пытаетесь построить импортера? Измените свой вопрос, чтобы уточнить. –

+0

Также: у вас есть дополнительный вопрос (относительно слияния), который вы должны рассмотреть отдельно. –

+0

Отредактировано, и если его достаточно просто ответить здесь, пожалуйста, сделайте это, для меня это часть моей проблемы (попытка сделать все с одним запросом и разделить его на несколько) – rambossa

ответ

1

Вы можете передать JSON в качестве параметра в запрос Cypher и использовать UNWIND для перебора массивов в JSON.

Например (взято из this blog post), предположим, что ваш JSON выглядит следующим образом:

{ "items": [{ 
"question_id": 24620768, 
"link": "http://stackoverflow.com/questions/24620768/neo4j-cypher-query-get-last-n-elements", 
"title": "Neo4j cypher query: get last N elements", 
"answer_count": 1, 
"score": 1, 
..... 
"creation_date": 1404771217, 
"body_markdown": "I have a graph....How can I do that?", 
"tags": ["neo4j", "cypher"], 
"owner": { 
    "reputation": 815, 
    "user_id": 1212067, 
    .... 
    "link": "http://stackoverflow.com/users/1212067/" 
}, 
"answers": [{ 
    "owner": { 
     "reputation": 488, 
     "user_id": 737080, 
     "display_name": "Chris Leishman", 
     .... 
    }, 
    "answer_id": 24620959, 
    "share_link": "http://stackoverflow.com/a/24620959", 
    .... 
    "body_markdown": "The simplest would be to use an ... some discussion on this here:...", 
    "title": "Neo4j cypher query: get last N elements" 
}] 
} 

Проходя этот объект JSON в качестве параметра для Cypher запроса, чтобы вставить его в график будет выглядеть следующим образом:

WITH {json} as data 
UNWIND data.items as q 
MERGE (question:Question {id:q.question_id}) ON CREATE 
    SET question.title = q.title, question.share_link = q.share_link, question.favorite_count = q.favorite_count 
MERGE (owner:User {id:q.owner.user_id}) ON CREATE SET owner.display_name = q.owner.display_name 
MERGE (owner)-[:ASKED]->(question) 
FOREACH (tagName IN q.tags | MERGE (tag:Tag {name:tagName}) MERGE (question)-[:TAGGED]->(tag)) 
FOREACH (a IN q.answers | 
MERGE (question)<-[:ANSWERS]-(answer:Answer {id:a.answer_id}) 
MERGE (answerer:User {id:a.owner.user_id}) ON CREATE SET answerer.display_name = a.owner.display_name 
MERGE (answer)<-[:PROVIDED]-(answerer)) 

Есть еще несколько примеров этого here и here.

Относительно вашей проблемы с MERGE. MERGE просматривает весь шаблон и будет «получать или создавать» на основе всего указанного шаблона. Обычно вы хотите использовать MERGE в одном свойстве узла, чтобы гарантировать, что узел не дублируется вместо более крупного шаблона. Посмотрите на раздел MERGE this blog post для более подробной информации.

+0

awesome thank you – rambossa