Cypher Query不返回不存在的关系

时间:2016-06-03 09:25:24

标签: neo4j cypher graph-databases

我有一个图形数据库,其中有用户和兴趣节点通过 IS_INTERESTED 关系连接。我想找到用户未选择的兴趣。我写了这个查询并且它无法正常工作

OPTIONAL MATCH (u:User{userId : 1})-[r:IS_INTERESTED] -(i:Interest)
WHERE r is NULL
Return i.name as interest

根据关于SO的类似问题的答案(如this之一),上述查询应该可行。但是,在这种情况下,它返回null。但是在运行以下查询时,它按预期工作:

MATCH (u:User{userId : 1}), (i:Interest)
WHERE NOT (u) -[:IS_INTERESTED] -(i)
return i.name as interest

我不想运行上述查询的原因是因为Neo4j发出警告:

  

此查询在断开连接的模式之间构建笛卡尔积。

     

如果查询的一部分包含多个断开连接的模式,则为此   将在所有这些部分之间建立一个笛卡尔积。这可能   产生大量数据并减慢查询处理速度。而   偶尔打算,通常可以重新制定   查询,避免使用这个交叉产品,也许通过添加一个   不同部分之间的关​​系或使用OPTIONAL MATCH   (标识符为:(i))

在使用 OPTIONAL MATCH 查找不存在的关系的第一个查询中,我做错了什么?

3 个答案:

答案 0 :(得分:1)

当您的OPTIONAL MATCH查询未找到匹配项时,ri必须为NULL。毕竟,由于没有任何关系,因此无法获得它所指向的节点。

答案 1 :(得分:1)

1)MATCH正在寻找整体模式,如果找不到整体模式 - 不会返回任何内容。

2)我认为这个查询会有效:

// Take all user interests
MATCH (u:User{userId: 1})-[r:IS_INTERESTED]-(i:Interest)
    WITH collect(i) as interests
    // Check what interests are not included
    MATCH (ni:Interest) WHERE NOT ni IN interests
RETURN ni.name

答案 2 :(得分:0)

在OPTIONAL MATCH之后直接将拉入评估中。

如果你想要后期过滤,你必须在两者之间使用WITH。

MATCH (u:User{userId : 1})
OPTIONAL MATCH (u)-[r:IS_INTERESTED] -(i:Interest)
WITH r,i
WHERE r is NULL
Return i.name as interest