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
在Neo4j中,可以找到其关系是另一个节点的超集的所有节点吗';谁的关系?_Neo4j_Cypher - Fatal编程技术网

在Neo4j中,可以找到其关系是另一个节点的超集的所有节点吗';谁的关系?

在Neo4j中,可以找到其关系是另一个节点的超集的所有节点吗';谁的关系?,neo4j,cypher,Neo4j,Cypher,鉴于以下人为数据库: CREATE (a:Content {id:'A'}), (b:Content {id:'B'}), (c:Content {id:'C'}), (d:Content {id:'D'}), (ab:Container {id:'AB'}), (ab2:Container {id:'AB2'}), (abc:Container {id:'ABC'}), (abcd:Container {id:'ABCD'}), ((ab)-[:CONTAINS

鉴于以下人为数据库:

CREATE (a:Content {id:'A'}),
  (b:Content {id:'B'}),
  (c:Content {id:'C'}),
  (d:Content {id:'D'}),
  (ab:Container {id:'AB'}),
  (ab2:Container {id:'AB2'}),
  (abc:Container {id:'ABC'}),
  (abcd:Container {id:'ABCD'}),
  ((ab)-[:CONTAINS]->(a)),
  ((ab)-[:CONTAINS]->(b)),
  ((ab2)-[:CONTAINS]->(a)),
  ((ab2)-[:CONTAINS]->(b)),
  ((abc)-[:CONTAINS]->(a)),
  ((abc)-[:CONTAINS]->(b)),
  ((abc)-[:CONTAINS]->(c)),
  ((abcd)-[:CONTAINS]->(a)),
  ((abcd)-[:CONTAINS]->(b)),
  ((abcd)-[:CONTAINS]->(c)),
  ((abcd)-[:CONTAINS]->(d))
是否有一个查询可以检测所有
容器
节点对,其中一个
包含与另一个
容器
节点相同的
内容
节点的超集

对于我的示例数据库,我希望查询返回:

(ABCD) is a superset of (ABC), (AB), and (AB2)
(ABC) is a superset of (AB), and (AB2)
(AB) and (AB2) contain the same nodes
如果cypher不适用于此,但另一种查询语言也适用于此,或者如果Neo4j不适用于此,但另一个数据库也适用于此,我也将非常感谢您的意见

应答查询性能(截至2017-02-28221:56Z)

我在Neo4j或graph DB查询方面还没有足够的经验来分析答案的性能,我还没有构建大型数据集来进行更有意义的比较,但我认为我应该使用PROFILE命令运行每个数据集,并列出DB命中成本。我省略了计时数据,因为我无法使它与如此小的数据集保持一致或有意义

  • stdob--:129总db命中率
  • 戴夫·贝内特:总命中率46分贝
  • 反向频率:27 db总命中率

    • 这是第一次尝试。我相信这可能需要一些改进,但这应该让你去

      // find the containers and their contents
      match (n:Container)-[:CONTAINS]->(c:Content)
      
      // group the contents per container
      with n as container, collect(c.id) as contents
      
      // combine the continers and their contents
      with collect(container{.id, contents: contents}) as containers
      
      // loop through the list of containers
      with containers, size(containers) as container_size
      unwind range(0, container_size -1) as i
      unwind range(0, container_size -1) as j
      
      // for each container pair compare the contents
      with containers, i, j
      where i <> j
      and all(content IN containers[j].contents WHERE content in containers[i].contents)
      with containers[i].id as superset, containers[j].id as subset
      return superset, collect(subset) as subsets
      
      //查找容器及其内容
      匹配(n:Container)-[:CONTAINS]->(c:Content)
      //将每个容器中的内容分组
      使用n作为容器,收集(c.id)作为内容物
      //结合容器及其内容物
      使用collect(容器{.id,contents:contents})作为容器
      //循环浏览容器列表
      对于容器,大小(容器)为容器大小
      展开范围(0,容器大小-1)为i
      放卷范围(0,容器尺寸-1)为j
      //对于每个容器对,比较内容
      对于容器,i,j
      我在哪里
      和全部(容器中的内容[j]。其中容器中的内容[i]。内容)
      容器[i].id作为超集,容器[j].id作为子集
      返回超集,收集(子集)作为子集
      
      //获取每个容器的内容
      匹配(SS:容器)-[:包含]->(CT:内容)
      有党卫军,,
      将(不同的CT)收集为CT
      //使所有容器不等于SS
      匹配(T:容器)
      在哪里
      //对于每个容器,获取其内容
      匹配(T)-[:包含]->(CT:内容)
      //测试是否嵌套
      有党卫军,,
      中旅,
      T
      全部(ct在采集中(不同ct),其中ct在ct中)作为测试
      其中test=true
      返回SS,收集(T)
      
      在获取容器及其收集的内容后,我将使用的方法是通过内容计数筛选出哪些容器彼此比较,然后运行以筛选超集/相等集。最后,您可以比较内容的计数,以确定它是超集还是相等集,然后收集

      大概是这样的:

      match (con:Container)-[:CONTAINS]->(content)
      with con, collect(content) as contents
      with collect({con:con, contents:contents, size:size(contents)}) as all
      unwind all as first
      unwind all as second
      with first, second
      where first <> second and first.size >= second.size
      with first, second
      where apoc.coll.containsAll(first.contents, second.contents)
      with first, 
       case when first.size = second.size and id(first.con) < id(second.con) then second end as same, 
       case when first.size > second.size then second end as superset
      with first.con as container, collect(same.con) as sameAs, collect(superset.con) as supersetOf
      where size(sameAs) > 0 or size(supersetOf) > 0
      return container, sameAs, supersetOf
      order by size(supersetOf) desc, size(sameAs) desc
      
      匹配(con:Container)-[:CONTAINS]->(content)
      使用con,将(内容)收集为内容
      使用collect({con:con,contents:contents,size:size(contents)})作为所有
      先把所有的东西都解开
      以秒为单位全部展开
      第一,第二
      其中first second和first.size>=second.size
      第一,第二
      其中apoc.coll.containsAll(first.contents,second.contents)
      首先,
      当first.size=second.size且id(first.con)second.size然后第二个end作为超集时的情况
      使用first.con作为容器,collect(same.con)作为sameAs,collect(superset.con)作为supersetOf
      其中大小(sameAs)>0或大小(supersetOf)>0
      返回容器,sameAs,supersetOf
      按尺寸(超级)说明订购,尺寸(相同)说明
      
      Dave Bennett和stdob的回答似乎都给出了我要求的结果,谢谢。我对这两个都投了赞成票,一旦我在一个更大的数据集上尝试了它们,我就会给出一个答案,因为我不得不选择一个。关于在更大的数据集中有多少容器节点?我还没有组装它(这需要做一些工作,现在我知道我有可行的工具来完成后面的计算,这是我议程上的下一步)。然而,70000个集装箱似乎是一个现实的估计。每个容器的容量从几个到几百个不等,但平均可能有30个。
      match (con:Container)-[:CONTAINS]->(content)
      with con, collect(content) as contents
      with collect({con:con, contents:contents, size:size(contents)}) as all
      unwind all as first
      unwind all as second
      with first, second
      where first <> second and first.size >= second.size
      with first, second
      where apoc.coll.containsAll(first.contents, second.contents)
      with first, 
       case when first.size = second.size and id(first.con) < id(second.con) then second end as same, 
       case when first.size > second.size then second end as superset
      with first.con as container, collect(same.con) as sameAs, collect(superset.con) as supersetOf
      where size(sameAs) > 0 or size(supersetOf) > 0
      return container, sameAs, supersetOf
      order by size(supersetOf) desc, size(sameAs) desc