Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graph Neo4j中的内射匹配_Graph_Neo4j_Graph Databases - Fatal编程技术网

Graph Neo4j中的内射匹配

Graph Neo4j中的内射匹配,graph,neo4j,graph-databases,Graph,Neo4j,Graph Databases,我正在寻找一种在Neo4j中进行匹配的有效方法。如果你不确定我说的是什么意思;我只是希望返回匹配,其中匹配中返回的每个节点都是唯一的(例如,具有唯一的ID),并且路径也是如此 使用Wikipedia(上图)中的图,匹配的域X是模式中的节点和路径,协同域Y是数据库的内部图。上图是内射的,因为没有2个箭头从X点指向Y中的同一元素(因此模式中没有2个节点与图中的同一节点匹配,并且对边也是如此),而默认的Neo4J匹配是非内射的,允许模式中的2个节点与图中的同一节点匹配(你可以想象一个非内射匹配的例子

我正在寻找一种在Neo4j中进行匹配的有效方法。如果你不确定我说的是什么意思;我只是希望返回匹配,其中匹配中返回的每个节点都是唯一的(例如,具有唯一的ID),并且路径也是如此

使用Wikipedia(上图)中的图,匹配的域X是模式中的节点和路径,协同域Y是数据库的内部图。上图是内射的,因为没有2个箭头从X点指向Y中的同一元素(因此模式中没有2个节点与图中的同一节点匹配,并且对边也是如此),而默认的Neo4J匹配是非内射的,允许模式中的2个节点与图中的同一节点匹配(你可以想象一个非内射匹配的例子,如上图中X中1和2的箭头都指向Y中的D)。传统的图论将多个项目从域X匹配到同一个项目的共同域Y“合并”,但我可以理解,在这种情况下,这个术语可能会混淆

我可以通过指定匹配的节点是不同的来模拟特定查询:

match (a), (b) where not id(a) = id(b) return a, b
但我希望在一般意义上这样做,而不必在每个查询中都如此明确。因此,对于本例,我希望返回匹配,其中(a)和(b)是唯一节点,但我希望使用一些一般行为,而不是基于ID指定唯一性


当我查询时,路径似乎已经保证是唯一的,但如果有人能确认这一点,那就太好了。

我不确定您到底想要什么,但我可以升级您的查询以提高效率

Match (a),(b) where id(a) < id(b)
Return a,b 

注意:始终为节点使用标签,因为它可以加快查询执行

编辑:@InverseFalcon使用APOC插件提供了更好的解决方案,但如果您出于任何原因无法使用APOC或APOC支持停止,则您可以按照此处所述手动检查ID的唯一性

路径在设计上是唯一的,因此内射匹配可以通过简单地确保节点是唯一的来实现。受此启发,显然您无法包装查询来实现这一点,但WHERE子句中的简短ALL语句至少简化了id检查

如果要匹配的模式由以下内容描述:

MATCH p1=(a)-[r]->(b), (c)
RETURN a, b, c, p1
这是一个非常简单的模式(从第一个到第二个具有任何关系的任意3个节点),然后您可以通过检查每个节点的ID与其他节点的ID来确保这3个节点的唯一性:

MATCH p1=(a)-[r]->(b), (c)
WHERE ALL(n in [a, b, c] where 
          1=length(filter(m in [a, b, c] where id(m)=id(n))))
RETURN a, b, c, p1
这是通过检查我们希望唯一的节点集合中的每个节点([a,b,c]),并将其ID与该集合中每个其他节点的ID进行比较,确保集合中只有1个匹配ID(自身)。这就是“其中1=长度()”部分的原因

因此,通常使用这种思想,返回节点被保证是唯一的,来自模式的返回路径被保证是唯一的(通过Neo4j的设计),使得匹配过程是内射的


这不是一个理想的解决方案,因为语句必须从查询中自定义编写,但它至少是一个WHERE条件,该条件线性增长到节点数,而不是为每对节点创建一个条件,其中条件数按阶乘顺序增长到节点数。

如果您只想确保匹配中变量的节点不同,您可以安装并使用其中一些,特别是
apoc.coll.containsDuplicates()

示例用法可能如下所示:

MATCH p1=(a)-[r]->(b), (c)
WHERE NOT apoc.coll.containsDuplicates([a, b, c])
RETURN a, b, c, p1

所以匹配(a),(b)返回distinct(a)distinct(b)将确保a和b匹配到单独的节点?如果是这样,这正是我想要的。不,很遗憾不是。它只需要一个列表并从中删除重复项。您想要使用的是我编写的第一个查询…您能更具体地说明什么是用例吗不幸的不是真的;我正在尝试构建一个非常通用的模型,对吗现在,我们要建立一般意义上的内射匹配。如果你不确定我所说的内射匹配是什么意思:如果我有一组节点(v1,v2,…vn)和边(e1,e2,…em)我想找到这组节点和边的所有有效匹配项,其中没有两个节点或边被合并。我可以为每对节点和边生成一个where子句,正如您所描述的,但当我想匹配的节点/边的大小增加时,它会以二次方的方式爆炸。我不知道为什么人们会对此投反对票。我认为一个原因是您使用了一些术语are已经在Neo4j中使用,表示不同的含义。例如,“匹配的节点和路径未合并的位置”对于熟悉Neo4j术语“合并”的人来说相当混乱(在Neo4j中,合并是创建或匹配图形元素…匹配(如果存在)和创建(如果不存在)。你能用不同的术语来描述这个需求吗?@InverseFalcon一个公正的评论,我能想到的唯一有效的术语是匹配的节点和路径是唯一的(不同的可以工作,但显然在查询中用于不同的目的)。将此标记为答案,除非有更好的显示。这几乎看起来像是您试图查找具有特定设置大小的所有节点组合,没有重复。是否接近?在这个特定示例中,是的,但更一般地说,我只想返回没有合并节点或路径的匹配,并确保ID中没有重复是。通过将集合中任意模式的所有节点放入all子句中,这通常适用于匹配。同样,我希望使用Neo4j的匹配函数,但我希望它以内射方式进行操作(请参阅),而默认情况下它不会(也不是满射或双射的,但您可以忽略此上下文中的那些节点)@InverseFalcon我在示例中添加了一条路径,以使其更清楚地表明我希望为常规模式匹配执行此操作,并尝试尝试执行此操作,但我正在努力使APOC正确安装(我的neo4j.conf丢失-。-)。我完成此操作后将返回
MATCH p1=(a)-[r]->(b), (c)
WHERE NOT apoc.coll.containsDuplicates([a, b, c])
RETURN a, b, c, p1