Neo4J cypher可选属性或与集合的关系的有效比较

Neo4J cypher可选属性或与集合的关系的有效比较,neo4j,cypher,Neo4j,Cypher,爱丽丝喜欢小猫和小狗,只会去它们都在场的地方。她喜欢孔雀鱼和金鱼,并坚持至少有一只孔雀鱼和金鱼在场。她讨厌针鼹,也不会出现在任何有刺的地方。鲍勃喜欢小猫和仓鼠,但对其他动物没有强烈的感情,比如鱼、刺或其他动物 CREATE (alice:PERSON {name: 'Alice', loves: ['kittens','puppies'], likes: ['guppies','goldfish'], hates:['echidnas']}) CREATE (bob:PERSON {name:

爱丽丝喜欢小猫和小狗,只会去它们都在场的地方。她喜欢孔雀鱼和金鱼,并坚持至少有一只孔雀鱼和金鱼在场。她讨厌针鼹,也不会出现在任何有刺的地方。鲍勃喜欢小猫和仓鼠,但对其他动物没有强烈的感情,比如鱼、刺或其他动物

CREATE (alice:PERSON {name: 'Alice', loves: ['kittens','puppies'], likes: ['guppies','goldfish'], hates:['echidnas']})
CREATE (bob:PERSON {name: 'Bob', likes: ['kittens','hamsters']})
我要举办一个派对,在那里我会有小猫、小狗、孔雀鱼和海牛。谁会来?我是这样问的

MATCH (a:PERSON) 
WHERE 
(NOT HAS (a.loves) OR (LENGTH(FILTER(love IN a.loves WHERE love IN ['kittens','puppies','guppies','manatees'])) = LENGTH(a.loves)))
AND
(NOT HAS (a.likes) OR (LENGTH(FILTER(like IN a.likes WHERE like IN ['kittens','puppies','guppies','manatees'])) > 0))
AND
(NOT HAS (a.hates) OR (LENGTH(FILTER(hate IN a.hates WHERE hate IN ['kittens','puppies','guppies','manatees'])) = 0))
RETURN a.name
Huzzah、Alice和Bob都同意

然而,在Cypher中,这是最聪明的方法吗

这当然是一个玩具示例:在匹配和其他过滤条件中也会有一个形状

但是,我的重点是形状中的每个人都可以选择没有,一组两个或三个东西[*],其中一个包含的元素必须与所提供集合中的元素匹配,其中一个必须与任何元素匹配,另一个包含的元素不必与(公共)集合中的任何元素匹配提供收藏。实现这一点是一项核心要求

[*]我说的是“事物”而不是“属性”,因为我不反对将我的动物建模为节点,并将我的人与它们联系起来。就像这样,对于卡罗尔和丹来说,他们与爱丽丝和鲍勃在动物方面有着相同的品味

CREATE (carol:PERSON {name: 'Carol'})-[:LOVES]->(kittens {name:'kittens'}),
(carol)-[:LOVES]->(puppies {name:'puppies'}),
(carol)-[:LIKES]->({name:'guppies'}),
(carol)-[:LIKES]->({name:'goldfish'}),
(carol)-[:HATES]->({name:'echidnas'}),
(dan:PERSON {name: 'Dan'})-[:LIKES]->(kittens),
(dan)-[:LIKES]->({name:'hamsters'})

MATCH (a:PERSON), (a)-[:LOVES]->(a_loves), (a)-[:LIKES]->(a_likes), (a)-[:HATES]->(a_hates)
WHERE
ALL (loves_name IN a_loves.name WHERE loves_name IN ['kittens','puppies','guppies','manatees'])
AND
ANY (likes_name IN a_likes.name WHERE likes_name IN ['kittens','puppies','guppies','manatees'])
AND
NONE (hates_name IN a_hates.name WHERE hates_name IN ['kittens','puppies','guppies','manatees'])
RETURN a.name
这适用于每一个至少爱、喜欢和恨一种动物的人,即卡罗尔。然而,当一个人没有三种爱、喜欢和讨厌的关系时,它就不起作用了,因为在图表中找不到这种形状,因此也找不到丹。我看不出一个明显的方法来让可选匹配执行这种修剪

为了解决这个问题,我可以添加假动物节点,并为每个人提供它们的关系,因此:-[:爱]->(独角兽),-[:喜欢]->(曼蒂科里斯)-[:恨]->(蛇怪),然后始终将“独角兽”添加到与爱节点进行比较的集合中。然而,这感觉非常做作和笨拙

长文短文,你最喜欢的Neo4J和Cypher建模方式是什么?为什么?

这里是第一个剪辑

请看一看,让我知道,首先,问题是否被理解,其次,查询是否合适

我想稍后再回来改进这个查询,因为它很快就完成了