集合/ json Neo4j apoc

时间:2019-02-02 00:22:15

标签: json neo4j cypher neo4j-apoc

简短的任务描述:我有一个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"]
        }
    ],

    "target":[
        {"label":"Drinks",
        "tag":[],
        "type":"string",
        "xpath":[]
        },

        {"label":"Tea",
        "tag":["black", "green"],
        "type":"string",
        "xpath":["Drinks"]
        },

        {"label":"Carbonated water",
        "tag":[],
        "type":"string",
        "xpath":["Drinks","Tea"]
        },

        {
        "label":"Pepsi",
        "tag":["sweet","cheap"],
        "type":"string",
        "xpath":["Drinks","Tea","Carbonated water"]
        }
    ]
}

节点已经插入到数据库中,并且已建立相应的关系。节点已连接,因此可以建立从起点到目标的至少一条路径。

要找到最短路径,我正在使用以下Cypher查询:

    CALL apoc.load.json("file:///D:/project/neo_proj/input.json") YIELD value 
UNWIND value.origin AS orig UNWIND value.target AS tar 
MATCH(origin:concept{name:orig.label}) 
MATCH(target:concept{name:tar.label}), 
path = shortestPath((origin)-[*1..3]-(target)) RETURN path ORDER BY length(path) ASC LIMIT 4

此查询将所有原始节点映射到所有目标节点。但我需要这样的东西:

   CALL apoc.load.json("file:///D:/project/neo_proj/input.json") YIELD value
UNWIND value.origin AS orig UNWIND value.target AS tar 
MATCH(origin:concept{name:orig.label}) MATCH(target:concept{name:tar.label}) 
FOREACH (x IN orig.label 
| MERGE(origin:concept{name:orig.label}) 
MERGE(target:concept{name:tar.label}) 
path = shortestPath((origin)-[*1..3]-(target))) RETURN path ORDER BY length(path) ASC LIMIT 3

此查询不起作用,但想法是能够使用foreach循环,获取第一个原点标签,并尝试找到到一个目标的第1、2、3最短路径,然后找到第2个原点,第3个如果您能指出我,我将不胜感激,如何以正确的方式将foreach循环用于短路径查找。预先谢谢你!

1 个答案:

答案 0 :(得分:0)

您不能以这种方式使用FOREACH。

您最好的选择也许是使用APOC路径扩展程序proc,这些可以为最短路径使用bfs扩展,并且每次调用的结果数可能受到限制(并且将针对源的每一行配对执行一次调用和目标),因此使用正确的过程(在此处使用spanningTree()以确保我们只访问一次每个节点,并在最后返回路径),每个原始/目标组合最多可获得3条最短路径。

这也将有助于分别处理原点和目标,因为您当前的方法会在原点和目标之间创建笛卡尔积,这似乎是您寻找路径所需要的,但是当找到原点和目标时,这会浪费多余的匹配操作节点。

CALL apoc.load.json("file:///D:/project/neo_proj/input.json") YIELD value 
UNWIND value.origin AS orig 
MATCH(origin:concept{name:orig.label}) 
WITH value, collect(origin) as origins
UNWIND value.target AS tar 
MATCH(target:concept{name:tar.label})
UNWIND origins as origin
WITH origin, tar
CALL apoc.path.spanningTree(origin, {terminatorNodes:[tar], maxLevel:3, limit:3}) YIELD path
RETURN origin, tar, length(path) as pathLength, path