Neo4j如何从嵌套JSON中的值创建多个列表

时间:2018-07-16 10:12:37

标签: json neo4j cypher

我有此JSON数据:

{"title": "Title1", "authors": [{"name": "Dave Chappelle", "org": "MIT"}], "id": "abc123"}
{"title": "Title2", "authors": [{"name": "Rick Sanchez"}, {"name": "Amy Schumer"], "id": "xyz234"}

我想创建一些看起来像这样的信息:

[“author1”, “author2",... “authorN”]用于JSON文件中的每篇论文。

例如,对于第一行数据,列表将仅为["Dave Chappelle"]

列表的第二行数据为["Rick Sanchez, "Amy Schumer"]

一旦有了这个,我想使用这些列表中的每一个进行一些Cypher操作。具体来说,我想在论文和论文的每位作者之间创建一种关系,其中AUTHORED关系具有两个属性,即is_first_authoris_last_author,具有布尔值。

对于JSON文件中的单个数据,我知道以下工作可以识别给定列表中的元素,并为每个元素是第一个还是最后一个给出布尔值:

WITH [“author1”, “author2", “author3”, “author4"] AS authors
UNWIND range(0,size(authors)-1,1) as idx
return idx, authors[idx], idx=1 AS is_first_author, idx=size(authors)-1 as is_last_author

并返回

idx authors[idx]    is_first_author is_last_author
0   "author1"   false   false
1   "author2"   true    false
2   "author3"   false   false
3   "author4"   false   true

为了获得此作者列表并将这些属性添加到每个作者与其论文之间的关系中,我使用以下代码:

CALL apoc.load.json('file.txt') YIELD value AS q UNWIND q.id AS id UNWIND q.authors as authors
MERGE (i:Quanta {id:q.id}) 
MERGE (a:Author {name:authors.name})
FOREACH (quanta IN q.id | WITH quanta.authors as authors 
WITH collect(authors.name) as names 
UNWIND range(0,size(names)-1,1) as idx 
MERGE (a)-[:AUTHORED {is_first_author:idx=1}, {is_last_author: idx=size(authors)-1}]-(i)
            RETURN *;

但是,这给了我一个语法错误:

Invalid input ',': expected whitespace or ']' (line 4, column 177 (offset: 380))
"FOREACH (quanta IN q.id | WITH quanta.authors as authors WITH collect(authors.name) as names UNWIND range(0,size(names)-1,1) as idx MERGE (a)-[:AUTHORED {is_first_author:idx=1}, {is_last_author: idx=size(authors)-1}]-(i)"

我也很确定在WITH内使用FOREACH语句在语法上是无效的,但是我不确定如何执行此操作。

任何建议将不胜感激!

1 个答案:

答案 0 :(得分:1)

由于已经有了列表,因此可以通过head(list)last(list)来获得第一作者和最后作者,在展开列表之前,先执行此操作,然后保存比较,然后在末尾使用它。

另外,根据您的数据,id属性不是列表,因此无需取消它。仅在列表上使用UNWIND,因为它会将它们转换为行

CALL apoc.load.json('file.txt') YIELD value AS q 
WITH q.id AS id, head(q.authors).name as firstName, last(q.authors).name as lastName, q.authors as authors
UNWIND authors as author
MERGE (i:Quanta {id:id}) 
MERGE (a:Author {name:author.name})
WITH i, a, author.name = firstName as isFirstName, author.name = lastName as isLastName
MERGE (a)-[:AUTHORED {is_first_author:isFirstName, is_last_author:isLastName}]-(i)
RETURN *;

请注意,如果只有一位作者,则它将同时注册为第一作者和最后一位作者。

此外,如果列表中有重复的名称,可能会导致结果出错,但我怀疑数据在每个Quanta中是否具有重复的名称。