通过使用 Neo4j APOC 解析 JSON 获取数组的最后一个元素

Get last element of array by parsing JSON with Neo4j APOC

简短任务描述:我需要获取嵌套 JSON 中字段之一的 array/list 的最后一个元素,这里是输入 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" 字段的最后一个元素,以便与适当的 "label" 建立关系。这是代码,它创建与 "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)

其中 returns 只是一个数组数组或 "origin" 的所有 4 条记录中的所有 "xpath"。

我将不胜感激任何帮助,可能有一些变通方法(不是我提议的那样必要)来解决这个问题。提前致谢!

N.B。所有这些都应该在应用程序中完成,而不是在 Neo4j 浏览器中。

如果您只想获取原始对象中最后一个元素的 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)) 

听起来您正在寻找 last() 函数?这将 return 列表的最后一个元素。

在这种情况下,由于您将原点展开为 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