简体   繁体   中英

Neo4j Cypher Query To C# using 'WITH'

I want to get client who has two accounts, one is Type1 and another is Type2. Cygher query is as below


MATCH (client:Client)-[:OWNED_BY]-(account:Account)-[:TYPE_IN]-(type:Type) 
With client, account, type
MATCH (client)-[:OWNED_BY]-(account1:Account)-[:TYPE_IN]-(:Type{accountType: 'Type1'}) 
,(client)-[:OWNED_BY]-(account2:Account)-[:TYPE_IN]-(:Type{accountType: 'Type2'})
RETURN client, account, type

it works(any enhancement is welcome, but this is not my issue )

How I can convert it into C#? particularly 'With client, account, type' part. I had Neo4j.client

I managed to do this,


StringBuilder queryString =new StringBuilder();
            StringBuilder addtionQuery = new StringBuilder();

            queryString.Append("(client:Client)-[:OWNED_BY]-(account:Account)-[:TYPE_IN]-(type:Type)");

            addtionQuery.Append(String.Format("(client)-[:OWNED_BY]-(account0:Account)-[:TYPE_IN]-(:Type{{accountType: '{0}'}})"
                , searchCriteria.acctTypes[0]));

            for (int i = 1; i < searchCriteria.acctTypes.Length; i++)
            {
                if (searchCriteria.acctTypes[i] != null)
                {
                    addtionQuery.Append(",");
                    addtionQuery.Append(String.Format("(client)-[:OWNED_BY]-(account{1}:Account)-[:TYPE_IN]-(acct_type{1}:Type{{accountType: '{0}'}})", 
                        searchCriteria.acctTypes[i], i));
                }
            }


var query = Dbclient.Cypher
                .OptionalMatch(queryString.ToString())
                .With((client, account, type) => new 
                {
                    client = client.As<Client>(),
                    type = type.As<Demo1.Models.Type>(),
                    account = account.As<Account>()
                })
                .OptionalMatch(addtionQuery.ToString())
                .Return((client, account, type) => new QueryResult
                {
                    cif = client.As<Client>().cif,
                    type = type.As<Demo1.Models.Type>().accountType,
                    accountId = account.As<Account>().accountId
                })
                .Limit(searchCriteria.limit)
                .Results;

it works but result is not correct

I can't help you with the c# neo4jclient API, but your statement might be more efficient like this:

MATCH (client:Client)-[:OWNED_BY]-(account:Account)-[:TYPE_IN]-(type:Type) 
WHERE type.accountType IN ['Type1','Type2']
With client, collect([account, type]) as accounts
WHERE size(accounts) > 1
RETURN client, accounts

Well, your queries are different. Your Cypher query has MATCH clauses while your Neo4jClient query has OPTIONAL MATCH clauses, and you have different names for your nodes (account, account1, account2, ... <-> account, account0, ...).

I suggest you make sure that both queries are the same. You can use a debugger or print the resulting Cypher query with query.Query.QueryText or query.Query.DebugQueryText . In this case query is what you get before you call .Results on it, but your variable name is a bit off.

As far as WITH is concerned, the With() method can take a string as a parameter too, so you can simply write:

.With("client, account, type")

IMO, The With() that takes a lambda offers little or no gain over the one that takes a string , it's just more noise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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