Python neo4j:返回最长匹配修补程序上的所有节点
使用neo4j 1.9.4和py2neo 1.6,我的图中有一个类似二叉树的结构,其中每个节点最多有两个子节点。但是,该图不完整,因此可能看起来像这样,其中“(x)”表示节点,“[y]”表示关系Python neo4j:返回最长匹配修补程序上的所有节点,python,neo4j,cypher,py2neo,Python,Neo4j,Cypher,Py2neo,使用neo4j 1.9.4和py2neo 1.6,我的图中有一个类似二叉树的结构,其中每个节点最多有两个子节点。但是,该图不完整,因此可能看起来像这样,其中“(x)”表示节点,“[y]”表示关系 (root) / \ [0] [1] / \ (0) (1)
(root)
/ \
[0] [1]
/ \
(0) (1)
/ \ \
[0] [1] [1]
/ \ \
(00) (01) (11)
/
[0]
/
(000)
我在这里制作了一些类似的示例:(如果由于某种原因无法工作,您可以使用以下命令创建图形:
CREATE (node1 { name: '1' }),(node2 { name: '11' }),(node3 { name: '10' }),(node4 { name: '0' }),(node5 { name: '01' }),(node6 { name: '00' }),(node7 { name: '10' }),(root { name:'root' }), root-[:`1`]->node1, node1-[:`1`]->node2, node1-[:`0`]->node7, node2-[:`0`]->node3, root-[:`0`]->node4, node4-[:`1`]->node5, node4-[:`0`]->node6
我想返回(单个)特定路径上存在的所有节点
START root=node(1)
MATCH path = root-[?:`0`]-()-[?:`0`]-()-[?:`0`]-()
RETURN NODES(path)
(注意:设ID(root)=1)这将返回路径中的所有节点,即(0)、(00)和(000)
但是,由于我不知道每个分支的深度,我还想查询如下内容:
START root=node(1)
MATCH path = root-[?:`1`]-()-[?:`1`]-()-[?:`0`]-()-[?:`0`]-()
RETURN NODES(path)
此应返回可能最长路径上的所有节点,即(1)和(11)。事实上,此查询不返回任何内容。我如何实现此目的?注意:对于每个路径,我事先不知道此路径是否存在结束节点。我只想返回该路径上存在的所有节点
此外,使用py2neo(python)自动构造这样一个查询的最佳方法是什么。例如,我有一个包含多个路径的列表,我需要查询其中的每个路径。每个路径仅存在于“0”和“1”之外
list_of_paths = ["0010", "101", "11", "101110"]
谢谢大家
编辑:在这里()我可以找到一个类似的问题。但是,关系类型总是相同的,这不适用于我的场景。因此,我认为我不能从这里采用此解决方案
EDIT2:Wes的建议并不能解决我的问题:
START root=node(1)
MATCH path=root-[:`1`|`0`*]->leaf
RETURN path
此查询返回从根节点开始的所有可能路径。我想要的是一个特定路径的节点
START root=node(1)
MATCH path = root-[?:`0`]-()-[?:`0`]-()-[?:`0`]-()
RETURN NODES(path)
EDIT3:Wes的更新建议也不能解决我的问题。它只返回整个图中存在的最长路径。但我想查询一条特定的路径,并返回所有节点,直到路径不再存在于图中。因此,我可以查询一条非常长的路径,但在fa中ct路径已在第一个节点停止,例如根-[1
]->()-[0
]->()-…当路径在该点停止时,此查询应仅返回节点(1)。(节点(1)没有类型为0
的传出关系)
EDIT4:我试图找出一个有效的解决方案,但它相当肮脏
tree_root, = graph_db.create({"name": "root"}) # create a root
node_list = []
my_path = [1, 1, 0, 1, 1, 1] # path to query
len_of_path = len(my_path)
# add the corresponding number of nodes to the list and name them n0,..nX
for i in range(0,len_of_path):
node_list.append("n"+str(i))
# construct the query string
my_query_start = 'START root=node({root_id}) MATCH (root)'
my_query_return = ' RETURN'
for i in range(0, len(node_list)):
my_query_start += '-[?:`' + str(my_path[i]) + '`]->(' + str(node_list[i]) + ')'
if i == len(node_list)-1:
my_query_return += ' ' + str(node_list[i])
else:
my_query_return += ' ' + str(node_list[i]) + ','
# concatenate the query
complete_query = my_query_start + my_query_return
#print "complete_query:", complete_query
# execute the query
query_paths = neo4j.CypherQuery(graph_db, complete_query)
params = {"root_id" : tree_root._id}
my_list_of_nodes = query_paths.execute(**params)
#output results
print "data of my_list_of_nodes:", my_list_of_nodes.data
print "columns of my_list_of_nodes:", my_list_of_nodes.columns
伙计们,请不要告诉我这应该是最终的解决方案;-)您可以为reltype使用带OR的可变长度路径吗
MATCH path=root-***put your partial pattern here***->[:`1`|`0`*]->leaf
WHERE NOT (leaf)-[:`0`|`1`]->()
RETURN path
ORDER BY length(path) DESC
LIMIT 1
我认为它解决了你的例子。。。但是它比这更复杂吗?您的控制台示例似乎不起作用--您可以尝试再次保存它吗?这将从根目录返回所有可能的路径,对吗?但这不是我想要的。我想返回一个特定路径上的所有节点,尽管我无法判断该路径的结束节点是否存在。我的意思是将我的查询用作
匹配部分。因此,您可以使用以下命令:START root=node(1)match path=root-[:1
|0
*]->叶返回路径,但它肯定会返回从根开始的所有可能路径。我只想返回一个特定路径的节点。我想我还没有足够清楚地表达自己。您的建议提供的是完整图形中存在的最长路径,对吗?但我只想要特定路径中可能最长的路径。因此,一个场景是:给我可能路径根上存在的所有节点-[1
]-()-[1
]-[0
]-()-[1
]-()。这将返回节点(1)和(11),因为路径到此结束。希望这一点现在清楚了,然后将您的模式放在根之后,并在根之后加上叶。如果您的模式可能已经是最长的,并且您想要返回它,那么将*0..
放入。