I'm working on university course recommender system using Neo4j and have hit a brick wall with this problem.
What I want to do is give the system an interest, this interest will then be checked against students in the system who have a relationship with that interest (:HAS_INTEREST) and then return all the courses the students are enrolled in, with the frequency they appear in the search (the course(s) with the most students will be recommended). For that I use this query:
MATCH (interest:Interest {description:"Computing"})<-[:HAS_INTEREST]-(student:Student),
(student)-[:ENROLLED_IN]->(course:Course)
RETURN course.title, count(course) as frequency
ORDER BY frequency DESC
LIMIT 25
The query returns the data I want (course name and frequency of occurrence) when I type the query in using the Neo4j browser but my problem occurs when I try to make the cypher query in c#; I can't get the frequency for each course. I can return all the courses and even have then ordered but I need the frequency that they appeared to give a proper recommendation. I'll lay out my code below
Course Class
public class Course
{
public string title { get; set; }
public long fequency { get; set; }
}
Cypher Query
public static IEnumerable<Course> GetCourseRecommendation(string interest)
{
var data = GraphClient.Cypher
.Match("(i:Interest {description : {interestDesc} })<-[:HAS_INTEREST]-(student:Student)", "(student)-[:ENROLLED_IN]->(course: Course)")
.WithParam("interestDesc", interest)
.With((course, c) => new
{
course = course.As<Course>(),
c = course.Count()
})
.Return(course => course.As<Course>())
.OrderByDescending("c")
.Limit(25)
.Results;
return data;
}
I added the frequency attribute to the Course class to see if I could store it there but no luck, I've tried alot of different varations of the .net query to see if I can get the frequency out of it but nothing seems to work, it just returns the courses.
tl;dr I need to get the frequency of how many times a course appears in a query result and do not know how to get this information using the .Net library.
Edit : Answer
Thanks to Supamiu and Chris Skardon for giving an answer and an explanation to the issue. Final working query is listed below, this returns both the courses and the frequency that they appear in the query.
var data = GraphClient.Cypher
.Match("(i:Interest {description : {interestDesc} })<-[:HAS_INTEREST]-(student:Student)", "(student)-[:ENROLLED_IN]->(course: Course)")
.WithParam("interestDesc", interest)
.Return((course, c) => new
{
course = course.As<Course>(),
c = course.Count()
})
.OrderByDescending("c")
.Limit(25)
.Results;
Problem is that you store course
and frequency
in two different variables within your query, if you want to add frequency to your course, you'l have to set it later on like course.setFrequency(c)
.
Actually you are doing Return(course => course.As<Course>())
but course
only contains title, since frequency is stored in c
. So you have to get c
too and set it in course
later on.