如果属性数大于 n,则从 Neo4j 中的高连通图返回 [英] If the number of properties is greater than n, return from a highly connected graph in Neo4j

查看:17
本文介绍了如果属性数大于 n,则从 Neo4j 中的高连通图返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是我之前问过的问题的直接延伸

就像我之前问的问题一样,唯一真正有趣的是 SomeProperty 可以是是"或否".

在顶行中,三个节点中的 1 个对此属性具有是".

在底行,五个节点中的 3 个节点对此属性具有是".

(轻微的哲学旁注:我开始怀疑这是一个糟糕的图模式.为什么?因为,在每组节点中,每个节点都连接到每个其他节点.我'我不担心有两组节点的事实,但事实上,当我填充这个图时,我得到的回话说,'返回了 530 行.' 我认为这意味着实际上在图结构中创建了 530 个子路径和这似乎有点矫枉过正.)

无论如何,我试图解决的问题与我在更早、更简单、更线性的上下文中试图解决的问题几乎相同此处.

我想返回这些不相交图的完整路径,而在所述图中的任何地方,SomeProperty 的出现次数都大于 2.

我认为这是一个常见的简单问题.例如,假设你有两个不相关的家庭,有人说,给我看看家里有超过 2 个左撇子的人."

超级智能#cybersam 推荐用于这个问题的更简单的化身,大致如下:

MATCH p=(a:person)-[:RELATED_TO*]->(b:person)在哪里NOT ()-[:RELATED_TO]->(a) ANDNOT (b)-[:RELATED_TO]->() AND2<REDUCE(s = 0, x IN NODES(p) | CASE WHEN x. SomeProperty = 'Yes' THEN s + 1 ELSE s END)返回 p;

...如果图形更像一条直线,并且集合中的每个节点都没有与其他节点相关,则效果很好.

我认为#cybersam 的查询无法处理这个更复杂的图的原因是因为没有终端节点.

(另一个哲学旁注:我开始提出一种理论,即图中密集、复杂的关系会带来组合问题,包括性能和查询.我认为这可能是由于查询时 Cypher 使用的双向性?)

这是我的数据.感谢您的任何建议,并感谢您帮助我攀登学习曲线.

//match (n) detach delete n;CREATE (albert:person {gender: 'Male', name: 'Albert', SomeProperty: 'Yes'})创建(安妮:人{性别:'女性',姓名:'安妮',SomeProperty:'否'})CREATE (adrian:person {gender: 'Female', name: 'Adrian', SomeProperty: 'No'})创建(阿尔伯特)-[:RELATED_TO]->(安妮)创建(安妮)-[:RELATED_TO]->(阿尔伯特)创建(安妮)-[:RELATED_TO]->(阿德里安)创建(阿德里安)-[:RELATED_TO]->(安妮)创建(阿尔伯特)-[:RELATED_TO]->(阿德里安)创建(阿德里安)-[:RELATED_TO]->(阿尔伯特)CREATE (bill:person {gender: 'Male', name: 'Bill', SomeProperty: 'Yes'})创建(倒钩:人{性别:'女性',姓名:'倒钩',SomeProperty:'是'})CREATE (barry:person {gender: 'Male', name: 'Barry', SomeProperty: 'Yes'})CREATE (bart:person {gender: 'Male', name: 'Bart', SomeProperty: 'No'})CREATE (bartholemu:person {gender: 'Male', name: 'Bartholemu', SomeProperty: 'No'})创建(帐单)-[:RELATED_TO]->(倒钩)创建(倒钩)-[:RELATED_TO]->(账单)创建(倒钩)-[:RELATED_TO]->(巴里)创建(巴里)-[:RELATED_TO]->(倒钩)CREATE (barry)-[:RELATED_TO]->(bart)创建 (bart)-[:RELATED_TO]->(barry)创建 (bart)-[:RELATED_TO]->(bartholemu)创建 (bartholemu)-[:RELATED_TO]->(bart)CREATE (bill)-[:RELATED_TO]->(bartholemu)创建 (bartholemu)-[:RELATED_TO]->(bill)

解决方案

如果这是关于人的家庭,那么最简单的解决方法是为每个关系组添加一个 :Family 节点,如下所示:

create (f:Family) with f匹配 (a:person {name:"Adrian"})-[:RELATED_TO*]->(b:person)合并 (f:Family)<-[:FAMILY]-(a)合并 (f:Family)<-[:FAMILY]-(b)

将Adrian"替换为Barry"以创建第二个家庭组.

这为您提供了每个家庭组的中央 :Family 节点.然后,您可以选择有足够 :person.SomeProperty = "Yes" 家庭成员的家庭组,如下所示:

//查找有 2 个或更多的家庭 :person.SomeProperty = "yes"匹配 p = (f:Family)<-[:FAMILY]-(psn:person)其中 psn.SomeProperty = "是"用 f, count(psn) 作为 cnt其中 cnt >2//获取家庭成员匹配 (a:person)<-[r1:RELATED_TO]-(b:person)-[r2:RELATED_TO*]->(c)其中 (a)-[:FAMILY]-(f)and a = c//获取循环中的所有节点//报告第一条记录,它将有两个//家庭成员和所有关系返回 a, r1, b, r2限制 1

This question is a direct extension of a question I asked previously here (and and even earlier version here).

Say I have a graph database that looks like this:

Just like the previous questions I asked, the only really interesting thing about this is that SomeProperty can be 'Yes' or 'No'.

In the top row, 1 of the three nodes has a 'Yes' for this property.

On the bottom row, 3 nodes of the five nodes have a 'Yes' for this property.

(Slight philosophical sidenote: I'm starting to suspect that this is a bad graph schema. Why? Because, within each set of nodes, each node is in connected to every other node. I'm not worried about the fact that there are two groups of nodes, but the fact that when I populate this graph, I get talkback that says, 'Returned 530 rows.' I think this means actually created 530 subpaths within the graph structure and this seems like overkill.)

Anyway, the problem I'm trying to solve is pretty much the same as the problem I was trying to solve in the earlier, simpler, more linear context here.

I want to return the full path of either of these disjoint graphs, whereas anywhere within said graph the count the occurrences of SomeProperty is greater than 2.

I would think this is a common, simple problem. For example, say you had two unrelated families, and someone says, "Show me with family has more than 2 left handed people."

The super smart #cybersam recommended for the simpler incarnation of this problem, something along the lines of:

MATCH p=(a:person)-[:RELATED_TO*]->(b:person)
WHERE
  NOT ()-[:RELATED_TO]->(a) AND
  NOT (b)-[:RELATED_TO]->() AND
  2 < REDUCE(s = 0, x IN NODES(p) | CASE WHEN x. SomeProperty = 'Yes' THEN s + 1 ELSE s END)
RETURN p;

...which works great if the graph resembles more of a straight line, and doesn't have each node in the set related to each other node.

I think the reason why #cybersam's query won't handle this more complex graph is because there is no terminal node.

(Another philosophical sidenote: I'm starting to come up with a theories that dense, intricate relationships in a graph pose combinatorial problems, with performance as well as querying. I think this might be due to the bidirectionality used by Cypher when querying?)

Here's my data. Any advice is appreciate and thanks for helping me climb the learning curve.

// match (n) detach delete n;

CREATE (albert:person {gender: 'Male', name: 'Albert', SomeProperty: 'Yes'})
CREATE (annie:person {gender: 'Female', name: 'Annie', SomeProperty: 'No'})
CREATE (adrian:person {gender: 'Female', name: 'Adrian', SomeProperty: 'No'})

CREATE (albert)-[:RELATED_TO]->(annie)
CREATE (annie)-[:RELATED_TO]->(albert)
CREATE (annie)-[:RELATED_TO]->(adrian)
CREATE (adrian)-[:RELATED_TO]->(annie)
CREATE (albert)-[:RELATED_TO]->(adrian)
CREATE (adrian)-[:RELATED_TO]->(albert)


CREATE (bill:person {gender: 'Male', name: 'Bill', SomeProperty: 'Yes'})
CREATE (barb:person {gender: 'Female', name: 'Barb', SomeProperty: 'Yes'})
CREATE (barry:person {gender: 'Male', name: 'Barry', SomeProperty: 'Yes'})
CREATE (bart:person {gender: 'Male', name: 'Bart', SomeProperty: 'No'})
CREATE (bartholemu:person {gender: 'Male', name: 'Bartholemu', SomeProperty: 'No'})

CREATE (bill)-[:RELATED_TO]->(barb)
CREATE (barb)-[:RELATED_TO]->(bill)
CREATE (barb)-[:RELATED_TO]->(barry)
CREATE (barry)-[:RELATED_TO]->(barb)
CREATE (barry)-[:RELATED_TO]->(bart)
CREATE (bart)-[:RELATED_TO]->(barry)
CREATE (bart)-[:RELATED_TO]->(bartholemu)
CREATE (bartholemu)-[:RELATED_TO]->(bart)
CREATE (bill)-[:RELATED_TO]->(bartholemu)
CREATE (bartholemu)-[:RELATED_TO]->(bill)

解决方案

If this is about families of people, then easiest fix is to add a :Family node for each relational group, like so:

create (f:Family) with f 
match (a:person {name:"Adrian"})-[:RELATED_TO*]->(b:person)  
merge (f:Family)<-[:FAMILY]-(a) 
merge (f:Family)<-[:FAMILY]-(b)

Replace "Adrian" with "Barry" to create the second family group.

That gives you a central :Family node for each family group. You can then pick the family group that has enough :person.SomeProperty = "Yes" family members like so:

// Find families with 2 or more :person.SomeProperty = "yes"
match p = (f:Family)<-[:FAMILY]-(psn:person)
where psn.SomeProperty = "Yes"
with  f, count(psn) as cnt 
where cnt > 2

// Get the family members 
match (a:person)<-[r1:RELATED_TO]-(b:person)-[r2:RELATED_TO*]->(c)
where (a)-[:FAMILY]-(f)
  and a = c  // to get all the nodes in the loop 

// report the first record which'll have two  
// family members and all the relationships
return a, r1, b, r2 
limit 1

这篇关于如果属性数大于 n,则从 Neo4j 中的高连通图返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆