Neo4J most and least shots of the teams in the season - neo4j

i have a graph database and i am trying to find out which team has the most and the least shots in the season. i got until this pointenter image description here
Could you give me some hints how to find out the number of shots?

There is a problem with design . Ideally, You have to give common label(like "Team") for all the teams . And relation with event anyway can help in finding which is away team and which is home team and number of shots can be a property in the relation.
i would like to know if there are multiple nodes for same team in your graph to help you in this case.

You could use ORDER BY keyword to sort by shots, e.g.
RETURN a.away_shorts, m.away_team, m.home_team, b.home_shots
ORDER BY a.away_shots
//sort by order ascending, use ORDER BY a.away_shots DESC to reverse
If you wanted to only return the first team with, for example the least away shots, you might do something like this:
MATCH (a.AwayTeam)-[:PLAYED_AWAY]->(m:Event)<-[:PLAYED_HOME]-(b:HomeTeam)
RETURN a.away_shots, m.away_team, m.home_team, b.home_shots
ORDER BY a.away_shots LIMIT 1

Related

Is this cypher neo4j query working as I expect?

So I have a graph with Users and Places. Users are r:MEMBER_OF Places. I want to find suggestions of Places that a User might like to be a MEMBER_OF based on what Users are in which Places. So if a User is already in 1 Place, and many other users that are in that 1 Place are also in another Place, then that Place should be suggested, as long as the original User is not already in that Place.
So here's what I've come up with, and it does yield results, but I want to make sure that the suggested Places are not just random. Is this query properly ranking Places that should be suggested? Or is it just a random collection of Places that fit the criterion?
MATCH (a:User {username:'johndoe123'})-[:MEMBER_OF]->()<-[:MEMBER_OF]-(b:User)
MATCH (b)-[r:MEMBER_OF]->(suggestion)
WHERE NOT (a)-[:MEMBER_OF]->(suggestion)
RETURN suggestion limit 5
You are close, but you are return a suggestion every time another user is associated with that Place. You probably only want to return each Place suggestion once, and you probably want to rank the suggestions by their frequency. Try this.
MATCH (a:User {username:'johndoe123'})-[:MEMBER_OF]->()<-[:MEMBER_OF]-(b:User)
MATCH (b)-[r:MEMBER_OF]->(suggestion)
WHERE NOT (a)-[:MEMBER_OF]->(suggestion)
RETURN suggestion, count(*) AS otherUserCount
ORDER BY otherUserCount DESC limit 5

Can graph database query "nodes that a given node has no relationship with"?

I am working on a dating app where users can "like" or "dislike" other users and get matched.
As you can imagine the most important query of the app would be:
Give me a stack of nearby user profiles that I have NOT liked/disliked before.
I tried to work on this with a document database (Firestore) and figured it's simply not suitable for such kind of application and hence landed in the graph database world which is new and fascinating to me.
I understand that by nature a graph database retrieves data by tracing through the relationships and make relationships first-class citizens. My question now is that what if the nodes that I am trying to get are those with no relationship from the given node? What would the query look like? Can anyone provide an example query?
Edit:
- added nearby criteria to the query statement
This is definitely possible, here is a query example :
MATCH (me:Profile {name: "Chris"})
MATCH (other:Profile) WHERE NOT (other)-[:LIKES]->(me)
As stated in the comments of your original question, on a large dataset it might not scale well, that said it is pretty uncommon that you would use only one criteria for matching, for example, the list of possible profiles to match from can be grouped by :
geolocation
profiles in depth 2 ( who is liking me, then find who other people they like, do those people like me ? )
shared interests
age group
skin color
...

Cypher (Neo4j) - Find all relationships as long as one relationship from node satisfies a condition regardless of search path?

Excuse the bad title, I'm a beginner with Cypher and Graph databases in general. I'm not sure if the title fully captures what I am trying to ask, please let me know if you have any better titles!
I have a very simple graph setup with User nodes and Movie nodes and there exists a relationship from a User to a Movie called :REVIEWED that has a rating property that carries the users rating (1.0-5.0 inclusive). See the diagram below:
I think this design makes sense for a movie system for capturing user reviews. I don't think that reviews should exist as their own nodes because they are better represented as a relationship between the user (reviewer) and the movie in a graph. Not to mention the entire purpose properties can exist in relationships are to express scale/weight/metadata in a relationship and this is a great use case for them. However, due to this design I have been having a hard time coming up with a Cypher query to do the following:
Find the top ten movies with at least one review rating less than 3.
So that is, we want to sort the movies based on their average rating however at least one review must be less than a score of 3.0. The query I used to sort the movies based on their average rating is:
MATCH (movie:Movie)<-[review:REVIEWED]-(user:User)
RETURN movie.movieTitle, avg(review.rating) as avgRating
ORDER BY avgRating DESC
LIMIT 10
This makes sense to me, however when I try to limit the path to reviews with a rating less than 3, see below:
MATCH (movie:Movie)<-[review:REVIEWED]-(:User)
WHERE review.rating < 3
RETURN movie.movieTitle, avg(review.rating) as avgRating
ORDER BY avgRating DESC
LIMIT 10
Only the paths that have relationships with a rating less than 3 get matched, which is what I should get. However, the issue is when we average the ratings it's only averaging the ratings less than 3.0.
Ideally we want to have all the reviews for that movie as long as there exists a review for that movie with a rating less than 3.0 regardless of whether it is in the matched path. This is where I am getting confused. Because Cypher uses patterns to match paths in the graph how can we use it to check all paths from a node and see if a condition is satisfied and then continue to match all paths based on that result.
Looking forward to hearing what you guys think, thanks in advance!
You need a two section query first match movies that have review score undere 3, then average their ratings,
MATCH (movie:Movie)<-[review:REVIEWED]-(:User)
WHERE review.rating < 3
WITH DISTINCT movie
MATCH (movie)<-[review:REVIEWED]-(:User)
RETURN avg(review.rating) as avgRating
ORDER BY avgRating DESC
LIMIT 10

Approaches to tagging in Neo4j

I'm pretty new to Neo4j; I've only gotten as far as writing a hello world. Before I proceed, I want to make sure I have the right idea about how Neo4j works and what it can do for me.
As an example, say you wanted to write a Neo4j back end for a site like this. Questions would be nodes. Naïvely, tags would be represented by an array property on the question node. If you wanted to find questions with a certain tag, you'd have to scan every question in the database.
I think a better approach would to represent tags as nodes. If you wanted to find all questions with a certain tag, you'd start at the tag node and follow the relationships to the questions. If you wanted to find questions with all of a set of tags, you'd start at one of the tag nodes (preferably the least common/most specific one, if you know which one that is), follow its relationships to questions, and then select the questions with relationships to the other tags. I don't know how to express that in Cypher yet, but is that the right idea?
In my real application, I'm going to have entities with a potentially long list of tags, and I'm going to want to find entities that have all of the requested tags. Is this something where Neo4j would have significant advantages over SQL?
Kevin, correct.
You'd do it like that.
I even created a model some time ago for stackoverflow that does this.
For Cypher you can imagine queries like these
Find the User who was most active
MATCH (u:User)
OPTIONAL MATCH (u)-[:AUTHORED|ASKED|COMMENTED]->()
RETURN u,count(*)
ORDER BY count(*) DESC
LIMIT 5
Find co-used Tags
MATCH (t:Tag)
OPTIONAL MATCH (t)<-[:TAGGED]-(question)-[:TAGGED]->(t2)
RETURN t.name,t2.name,count(distinct question) as questions
ORDER BY questions DESC
MATCH (t:Tag)<-[r:TAGGED]->(question)
RETURN t,r,question

QuickBooks Item Query help needed

I'm sure this is going to be a long shot, but I need help with a query involving QuickBooks Items.
I need to query for all QuickBooks Items that are linked to an Income account. Is there an easy way to do this, or do I need to make 2 queries (one for items ans one for accounts) and then check the account reference?
albeit not much, I have this:
IItemQuery query = MsgSetRequest.AppendItemQueryRq();
any ideas would be appreciated. Thanks.
You need to use at least two queries. You'll need to fetch a list of accounts, and then compare the items AccountRef FullName to the income accounts in the list.
Using the XML, at least, if you query all items you can get back the accounts of all of them, and filter for the account that you want. The full name of the account will be included in the item query response if you specifically ask for it in IncludeRetElement.

Resources