Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find shortest Path between two nodes and return the paths. #427

Open
LouisBossekko opened this issue Oct 14, 2021 · 4 comments
Open

Find shortest Path between two nodes and return the paths. #427

LouisBossekko opened this issue Oct 14, 2021 · 4 comments

Comments

@LouisBossekko
Copy link

LouisBossekko commented Oct 14, 2021

Hey there,

I am new to cypher and neo4j and looking for a sulution to find the shortest path between two nodes.

This code worked on planc cypher for me, but i need it for the client:

MATCH 
    (skill:ISkill {Id: '9d20aaa0-b5fd-46e2-ad80-a7fda1755401'}),
    (degree:IDegree {Id: '67caaa58-aa08-4a7e-9f76-800b804cb888'}),
    p = shortestPath((skill)-[*..15]-(degree))
RETURN p

I tried a different approach with this Method to match the Relations to ISkillRating but i only got return count = 0

public async Task<SkillRating> GetSkillRatingForSkillAndDegree(Guid skillId, Guid degreeId)
{
            try
            {
                var result = await _client.Cypher
                    .Match("(iSkill:ISkill)-[r]-(iSkillRating:ISkillRating)")
                    .OptionalMatch("(iSkillRating:ISkillRating)-[r]-(iDegree:IDegree)")
                    .Where((ISkill iSkill) => iSkill.Id == skillId)
                    .AndWhere((IDegree iDegree) => iDegree.Id == degreeId)
                    .Return(iSkillRating => iSkillRating.As<SkillRating>())
                    .ResultsAsync;
                return result.FirstOrDefault();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
}

Does anybody know the command or function, which has to be called?

@cskardon
Copy link
Member

Hi @LouisBossekko

I'm not sure what you're trying - the Cypher you say works, vs the .NET code you've written are dramatically different.

The p you're returning in the cypher is a Path.
Which is not the SkillRating you're attempting to return from the .NET code.

Does the Cypher translation of your .NET code work?
You can see what Neo4jClient is generating by changing your code to look more like this:

public async Task<SkillRating> GetSkillRatingForSkillAndDegree(Guid skillId, Guid degreeId)
{
	try
	{
		var query = _client.Cypher
			.Match("(iSkill:ISkill)-[r]-(iSkillRating:ISkillRating)")
			.OptionalMatch("(iSkillRating:ISkillRating)-[r]-(iDegree:IDegree)")
			.Where((ISkill iSkill) => iSkill.Id == skillId)
			.AndWhere((IDegree iDegree) => iDegree.Id == degreeId)
			.Return(iSkillRating => iSkillRating.As<SkillRating>());

                //This line here!
		Console.WriteLine($"Query: {query.Query.DebugQueryText}");
		
		var result = await query.ResultsAsync;
		return result.FirstOrDefault();
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex);
		throw;
	}
}

@LouisBossekko
Copy link
Author

LouisBossekko commented Oct 15, 2021

Hey there @cskardon ,
thanks for the answer.
Yes its true, that these two approaches are very diffrent.
I first tried to make the approach with the .net client, but failed.
After an hour of testing i tried the path sultion in plain cypher.

The return of SkillRating is the desired outcome, but because this Method didn't work for me i tried the path solution.
Maybe there is something i am missing:
I Want to return SkillRating and it looks like this in the graph:

Skill =HasRating => SkillRating =For=> Degree

The input values are the ID of Skill and Degree.
My first approach was the Method in my first question.
I cant see whats wrong with it, but suspect that the matches are wrong!

@cskardon
Copy link
Member

So, I guess, do you have a working Cypher statement which does return the SkillRating using the MATCH statements?

My assumption would be that Skill and Degree have to be there, so I wouldn't be using an OPTIONAL MATCH - but is that right?

I would probably be writing something like:

var query = _client.Cypher
    .Match("(iSkill:ISkill)-[:HasRating]->(iSkillRating:ISkillRating)-[:For]->(iDegree:IDegree)")
    /*The rest*/

@LouisBossekko
Copy link
Author

LouisBossekko commented Oct 19, 2021

Thank you very much @cskardon .
This solved my problem.
I wasn't aware that you can match more than one relation in a match statement!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants