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

时间:2014-02-07 11:50:04

标签: neo4j cypher

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

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中最明智的方法吗?

这当然是一个玩具示例:MATCH中还有一个形状和其他过滤条件。

然而,我的重点是形状中的每个人可选择没有,一个或两个或三个东西[*],其中一个包含必须与所提供的集合的元素匹配的元素,其中一个ANY必须匹配,并且包含NONE必须与(common)提供的集合中的任何内容匹配的元素。实现这一点是一项核心要求。

[*]我说“事物”而不是“属性”,因为我不反对将动物建模为节点,并将我的人与他们联系起来。像这样,对于Carol和Dan来说,他们可以像Alice和Bob一样方便地分享动物的味道。

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

这适用于每个爱过的人,喜欢和讨厌至少一种动物,即卡罗尔。但是,当一个人没有所有三个LOVES和LIKES和HATES关系时,它不起作用,因为在图中找不到该形状,因此它找不到Dan。我看不出一种明显的方法可以让OPTIONAL MATCH进行那种修剪。

为了解决这个问题,我可以添加虚假的动物节点并给予它们每一个PERSON关系,因此: - [:LOVES] - >(unicorns), - [:LIKES] - >(manticores) - [:HATES] - >(basilisks)然后总是将'unicorns'添加到与LOVES节点进行比较的集合中。然而,这感觉非常狡猾和笨重。

长篇文章简介,在Neo4J和Cypher中建模的最佳方式是什么?为什么?

1 个答案:

答案 0 :(得分:1)

这是第一次剪切http://gist.neo4j.org/?8932364

请先看看让我知道,首先,问题是理解的,其次,如果查询适合。

我想稍后回来并改进这个问题,它很快就会被整合在一起。