我对Neo4j还有点新鲜感,所以也许我在某个地方错过了一些明显的写作,但在我的搜索中我还没有真正看到过这种情况,所以这里 - < / p>
我有一种情况,我正在制作一个Neo4j查询构建器,它从JSON字符串构造Neo4j查询,并且我试图找出匹配关系的效率问题。我需要能够处理存在/不存在关系的情况或应用过滤器(例如,查找拥有公司或具有&#34;活动&#34;属性设置为&的所有联系人#34; false&#34;)我试图找出最有效的方法来解决这个问题。
我似乎没有涉及&#34;不是[模式]&#34;在WHERE子句中工作 - 例如,尝试
MATCH (cn:contact), (cmp:company)
WHERE NOT (cn)-[]-(cmp)
RETURN cn, cmp
向我抛出所有联系人和公司。因此,似乎我绝对需要使用可选匹配来执行此操作,这是一个我可以做的实现,没有太多问题。
但是,我可以做类似
的事情MATCH (cn:contact), (cmp:company)
WHERE (cn)-[]-(cmp)
RETURN cn, cmp
只获取相关的联系人和公司,这意味着我不会 使用可选的匹配来解决这种情况。当关系存在或关系不存在时,它会简化我的查询解析以使用可选匹配,但我已经读过多个可选MATCH子句可能导致效率问题。有谁知道WHERE (cn)-[]-(cmp)
和OPTIONAL MATCH (cn)-[r]-(cmp) WITH cn,cmp,r WHERE r IS NOT NULL
之间的效率差异是否存在?
答案 0 :(得分:3)
[更新]
看起来您的原始查询(下面复制)旨在让所有与任何公司没有关系的联系人:
MATCH (cn:contact), (cmp:company)
WHERE NOT (cn)-[]-(cmp)
RETURN cn, cmp;
如果是这样,上述查询无法按预期工作,因为它实际上返回了它们之间没有关系的所有联系人和公司对。这与返回与任何公司没有关系的所有联系人不同。要做到这一点,这将有效:
MATCH (cn:contact)
WHERE NOT (cn)--(:company)
RETURN cn;
在对此答案的评论中,您询问是否可以执行查询,例如&#34;查找与名称以字母开头的公司没有关系的所有联系人&#39; A& #39;&#34;在WHERE
子句中(而不是必须使用OPTIONAL MATCH
)。答案是肯定的,至少在neo4j 3.1(目前pattern comprehension)中使用添加到Cypher的in beta功能时。
首先,您可以使用OPTIONAL MATCH
返回此类联系人的集合:
MATCH (cn:contact)
OPTIONAL MATCH (cn)--(cmp:company)
WHERE cmp.name STARTS WITH 'A'
RETURN [x IN COLLECT({cmp:cmp, cn:cn}) WHERE x.cmp IS NULL | x.cn] AS cns;
以下是如何使用3.1中Cypher的新pattern comprehension
工具在没有OPTIONAL MATCH
的情况下执行相同操作(下面的查询以行而不是单个集合的形式返回结果):< / p>
MATCH (cn:contact)
WHERE SIZE([(cn)--(cmp:company) WHERE cmp.name STARTS WITH 'A' | 0]) = 0
RETURN cn;
注意pattern comprehension
如何允许您以指定的模式定义新的本地标识符cmp
,并在本地使用它。这种模式理解创建了一个由零组成的集合(可以是任何值,因为我们实际上并不使用它) - 每个相关公司的名称以&#39; A&#39;开头。如果集合的大小为0,则WHERE
子句的计算结果为true
。