Получить последний элемент массива, проанализировав JSON с Neo4j APOC - PullRequest
0 голосов
/ 30 января 2019

Краткое описание задачи: мне нужно получить последний элемент массива / списка одного из полей во вложенном JSON, здесь входной файл JSON:

{
    "origin": [{
            "label": "Alcohol drinks",
            "tag": [],
            "type": "string",
            "xpath": []
        },
        {
            "label": "Wine",
            "tag": ["red", "white"],
            "type": "string",
            "xpath": ["Alcohol drinks"]
        },
        {
            "label": "Port wine",
            "tag": ["Portugal", "sweet", "strong"],
            "type": "string",
            "xpath": ["Alcohol drinks", "Wine"]
        },
        {
            "label": "Sandeman Cask 33",
            "tag": ["red", "expensive"],
            "type": "string",
            "xpath": ["Alcohol drinks", "Wine", "Port wine"]
        }
    ]
}

Мне нужно получить последний элементполя "xpath", чтобы создать связь с соответствующей меткой.Вот код, который создает соединение со всеми элементами, упомянутыми в «xpath», мне нужно просто подключиться к последнему:

WITH "file:///D:/project/neo_proj/input.json" AS url 
CALL apoc.load.json(url) YIELD value 
UNWIND value.origin as or 
MERGE(label:concept{name:or.label}) 
ON CREATE SET label.type = or.type 
FOREACH(tagName IN or.tag | MERGE(tag:concept{name:tagName}) 
MERGE (tag)-[r:link]-(label) 
ON CREATE SET r.Weight=1 
ON MATCH SET r.Weight=r.Weight+1)  
FOREACH(xpathName IN or.xpath | MERGE (xpath:concept{name:xpathName})
                                MERGE (label)-[r:link]-(xpath))

Возможно, есть что-то вроде:

apoc.agg.last(or.xpath)

который возвращает только массив массивов или все «xpath» из всех 4 записей «origin».

Буду признателен за любую помощь, возможно, есть некоторые обходные пути (не обязательные, как я предлагал) для решения этой проблемы.Заранее спасибо!

NB. Все это должно быть сделано из приложения, а не из браузера Neo4j.

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Похоже, вы ищете функцию last()?Это вернет последний элемент списка.

В этом случае, поскольку вы УВЕЛИЧИТЕ начало координат на 4 строки, вы получите последний элемент списка для каждой из этих строк.

WITH "file:///D:/project/neo_proj/input.json" AS url 
CALL apoc.load.json(url) YIELD value 
UNWIND value.origin as or 
RETURN last(or.xpath) as last
0 голосов
/ 31 января 2019

Вероятно, самым простым способом было бы разделить этот запрос на два запроса, если вы хотите взять только массив xpath последнего элемента в исходном объекте.

Запрос: 1

WITH "file:///D:/project/neo_proj/input.json" AS url 
CALL apoc.load.json(url) YIELD value 
UNWIND value.origin as or 
MERGE(label:concept{name:or.label}) 
ON CREATE SET label.type = or.type 
FOREACH(tagName IN or.tag | MERGE(tag:concept{name:tagName}) 
MERGE (tag)-[r:link]-(label) 
ON CREATE SET r.Weight=1 
ON MATCH SET r.Weight=r.Weight+1)

Запрос 2:

WITH "file:///D:/project/neo_proj/input.json" AS url 
CALL apoc.load.json(url) YIELD value 
WITH value.origin[-1] as or 
MATCH(label:concept{name:or.label})
FOREACH(xpathName IN or.xpath | MERGE (xpath:concept{name:xpathName})
                                MERGE (label)-[r:link]-(xpath))

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

WITH "file:///D:/project/neo_proj/input.json" AS url 
CALL apoc.load.json(url) YIELD value 
UNWIND value.origin as or 
MERGE(label:concept{name:or.label}) 
ON CREATE SET label.type = or.type 
FOREACH(tagName IN or.tag | MERGE(tag:concept{name:tagName}) 
MERGE (tag)-[r:link]-(label) 
ON CREATE SET r.Weight=1 
ON MATCH SET r.Weight=r.Weight+1)
// Any aggregation function will break the UNWIND loop 
// and return a single row as we want to write it only once
WITH value.origin[-1] as last, count(*) as agg
FOREACH(xpathName IN last.xpath | 
                                MERGE(label:concept{name:last.label})
                                MERGE (xpath:concept{name:xpathName})
                                MERGE (label)-[r:link]-(xpath)) 
...