如何做一个' OR'在NEO4J cypher中搜索

时间:2018-06-11 16:31:10

标签: neo4j cypher

我在节点上有一个带有不同标签的Neo4j数据库,例如:Banker,b:Customer。每个都有一个电子邮件属性我想搜索一个电子邮件,但不搜索整个数据库。所以我想做这样的比赛(a:Banker {email:' 123@mymail.com'})或匹配(b:客户{email:' 123@mymail.com' ;})。两个标签的电子邮件都有限制,但我不希望每个标签都有相同的电子邮件,因此在添加节点之前,我需要确定电子邮件是否存在于Banker或Customer节点中。我怀疑这可以通过一种非常有效的可扩展方式完成,在尝试添加百万分之一的记录时不会让用户盯着微调器......任何帮助都会非常感激

2 个答案:

答案 0 :(得分:3)

我如何做到这一点是有一个额外的标签' Person'所有银行家和客户。

CREATE CONSTRAINT ON (b:Person) ASSERT p.Email IS UNIQUE
CREATE CONSTRAINT ON (b:Banker) ASSERT p.Email IS UNIQUE
CREATE CONSTRAINT ON (b:Customer) ASSERT p.Email IS UNIQUE

CREATE (b:Person:Banker {Email: "123@mymail.com"})
CREATE (b:Person:Customer {Email: "321@mymail.com"})
CREATE (c:Person:Customer {Email: "123@mymail.com"})

最后一个将失败,因为Person / Banker已经拥有相同的电子邮件。然后你也可以搜索MATCH(p:Person {Email:" 123@mymail.com"})甚至b:Banker,c:Customer

如果一个人都是三个人,你也可以(p:人:顾客:银行家)。

它还允许你MERGE创建一个条目,如果它还没有存在。

由于您已拥有数据库,因此可以执行以下操作:

MATCH(b:Banker)
SET b:Person

MATCH(c:Customer)
SET c:Person

答案 1 :(得分:1)

  1. 有点安全"比@Liam的方法更简单的是Person标签,没有BankerCustomer标签。这样,在没有Person标签的情况下意外创建/合并节点会更加困难,因为这将是一个人的唯一标签。此外,每次添加人员时,此方法都不需要进行2(或3)次唯一性检查。

    使用此方法,您还可以根据需要添加isCustomerisBanker布尔属性,并在:Person(isCustomer):Person(isBanker)上创建索引,以快速找到客户与银行家。

  2. 现在,如上所述,我想知道您是否真的需要isCustomerisBanker属性(或CustomerBanker标签) 。也就是说,Person节点是银行家和/或客户的事实可以从该节点的关系中导出。您的数据模型包含Bank节点以及它们与人之间的关系似乎是合理的。例如,在以下数据模型中,b是" XYZ银行",c是客户,bc都是银行家:

    (b:Person)-[:WORKS_AT]->(xyz:Bank {id:123, name: 'XYZ Bank'}),
    (c:Person)-[:BANKS_AT]->(xyz),
    (bc:Person)-[:BANKS_AT]->(xyz)<-[:WORKS_AT]-(bc)
    

    此查询可以找到所有银行家:

    MATCH (banker:Person)-[:WORKS_AT]->(:Bank)
    RETURN banker;
    

    这会找到所有客户:

    MATCH (banker:Person)-[:BANKS_AT]->(:Bank)
    RETURN banker;
    

    这会发现所有银行家也是同一家银行的客户:

    MATCH (both:Person)-[:WORKS_AT]->(:Bank)<-[:BANKS_AT]-(both)
    RETURN both;