简体   繁体   English

如何使用Neo4j的.net客户端检查两个节点之间是否存在关系

[英]How to check if a relation exists between two nodes using .net client of neo4j

I have a role based application and 2 nodes Role and Cartable and i am managing my permissions by creating a relation between these 2 nodes, if a relationship exists between these two nodes means this role has a permission for example to view the Cartable: 我有一个基于角色的应用程序和2个节点RoleCartable ,我通过在这2个节点之间创建关系来管理权限,如果这两个节点之间存在关系,则意味着此角色具有例如查看Cartable的权限:

client.Cypher

            .Merge("(s:SiteConfiguration)-[:" 
            + Relations.ROLE_IN_SITE.ToString()+ "]-(r:Role)-[r1:"
            + Relations.ROLE_HAS_CARTABLE.ToString() + "]->(ca:Cartable)")
            .Where("r.Id = {param}").WithParam("param", roleId)
            .AndWhere("ca.Id= {param1}").WithParam("param1", cartableId)
            .AndWhere("s.SiteId= {param2}").WithParam("param2", MvcApplication.SiteConfigurations.Base.SiteId)
            .CreateUnique("(r)-[:" + Relations.EDIT_COMMENT.ToString()+"]-(ca)")
            .ExecuteWithoutResults();

Now i want to check if relation exists between two nodes and return a Boolean based on that so i wrote this: 现在,我想检查两个节点之间是否存在关系,并基于该关系返回一个布尔值,所以我这样写:

var q = new CypherFluentQuery(client) as ICypherFluentQuery;

q = q.Match("(s:SiteConfiguration)-[:" 
    + Relations.ROLE_IN_SITE.ToString() + "]-(r:Role)-[r1:" 
    + Relations.VIEW_CARTABLE.ToString() + "]-(c:Cartable)");
q = q.Where("s.SiteId= {param}").WithParam("param", MvcApplication.SiteConfigurations.Base.SiteId);
q = q.AndWhere("r.Id= {param1}").WithParam("param1", roleId);
q = q.AndWhere("c.Id= {param2}").WithParam("param2", cartableId);

But I'm not sure what i should return here, since VIEW_CARTABLE doesn't have any values as anonymous object on the relationship. 但是我不确定我应该在这里返回什么,因为VIEW_CARTABLE没有任何值作为关系上的匿名对象。 so my question is how to check if a certain relationship exists between these two nodes? 所以我的问题是如何检查这两个节点之间是否存在某种关系?

Because you are using a MATCH - you won't get any results if r1 is not there. 因为您使用的是MATCH如果r1不存在,则不会得到任何结果。 If you know you're going to get (s)-->(r) - but not sure about (r)-->(c) then you need to go OPTIONAL . 如果您知道要获得(s)-->(r) -但不确定(r)-->(c)则需要选择OPTIONAL

For example (using the :play Movies db): 例如(使用:play Movies数据库):

var query = gc.Cypher
    .Match("(p:Person {name:'Julia Roberts'})")
    .OptionalMatch("(p)-[r]->(m:Movie)")
    .Where("m.title = 'The Green Mile'")
    .Return((p, m) => new
    {
        Person = p.As<Person>(),
        Movie = m.As<Movie>(),
        IsInMovie = Return.As<bool>("NOT (r IS NULL)")
    });

Here I look for a person (Julia Roberts) and then try to see if she has a relationship to a given movie - in this case to one I know she's not in. 在这里,我寻找一个人(茱莉亚·罗伯茨),然后尝试看她是否与某部电影有关联-在这种情况下,与我知道她不在的一部电影有关。

I use an OptionalMatch to do this, and then check if r is null. 我使用OptionalMatch做到这一点,然后检查r是否为null。

Now, in practice - I don't need to know about r , as if there is no link to the movie, m will be null . 现在,在实践中-我不需要了解r ,就好像没有电影的链接一样, m将为null

In your case, you'd switch the top to be: 就您而言,您可以将顶部切换为:

var q = new CypherFluentQuery(client)
    .Match("(s:SiteConfiguration)-[:ROLE_IN_SITE]-(r:Role)")
    .OptionalMatch("(r)-[r1:VIEW_CARTABLE]-(c:Cartable)")
    .Where("s.SiteId= {param}").WithParam("param", MvcApplication.SiteConfigurations.Base.SiteId)
    .AndWhere("r.Id= {param1}").WithParam("param1", roleId)
    .AndWhere("c.Id= {param2}").WithParam("param2", cartableId)
    .Return((s,r,c,r1) => new {
        Site = s.As<SiteConfiguration>(),
        Role = r.As<Role>(),
        Cartable = c.As<Cartable>(),
        IsCartable = Return.As<bool>("NOT (r1 IS NULL)")
        });

And you can either check if IsCartable is true or if Cartable == null 您可以检查IsCartable是否为trueCartable == null

我认为应该足以确定r1是否不为null,因为获得非null值的唯一方法是关系是否存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM