У меня есть данные 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_author и is_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 синтаксически неверно, но я не совсем уверен, как это сделать в противном случае.
Любые предложения будут ценны!

Поскольку у вас уже есть список, вы можете получить первого и последнего автора по 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.
Имеет смысл, спасибо! Я скажу, что, хотя сам ID не является списком, мы использовали его, чтобы развернуть список всех документов, используя свойство ID. Возможно, я неправильно думал об этом, но до сих пор казалось, что это работает.