I have a graph database with people and cities. Is this query doing what I think it is doing
MATCH (c:City)-->(p:People)
RETURN c,count(p);
I want this query to be spitting back the city c with the count of the people in that city. However, the count is only one. This is either a problem with my loader or my query. Is the query giving me back what I think it is? Thanks
Your original query needs to change the direction.
MATCH (n:City)<--(p:Person)
RETURN n,count(p)
You need to have person going "into" city, and this returns the correct results for your example, as your example has 3 people "LIVES_IN" New York and 1 people "LIVES_IN" Boston, and that is what the query is returning in the console.
Related
I am using Neo4j 3.4 and am struggling with this particular query
MATCH (u:User)-[:IS_A_MEMBER_OF]->(c:Church)
RETURN size([(p:Post)<-[:POSTED]-(:User)-[:IS_A_MEMBER_OF]->(c) WHERE NOT (u)-[:ACKNOWLEDGED|POSTED]->(p) | p])
This query is designed to get the number of posts for the given Church that a user has not yet acknowledged and did not post themselves. In other words, it should retrieve all the posts by members of the church, then figure out which ones the user u has neither acknowledged or posted and return the count.
Unfortunately, I cannot figure out why Neo4j is not doing the check in the where clause. Is there something about pattern comprehensions that I am missing? Because the number returned is the same for all users, no matter whether they have acknowledged or posted any of the posts.
Thanks!
Here is a working example, I used count instead of size, size is for arrays and here you have a node row, count will aggregate all your row into a result.
MATCH (u:User)-[:IS_A_MEMBER_OF]->(c:Church),
(c)<-[:IS_A_MEMBER_OF]-(:User)-[:POSTED]->(p:Post)
WHERE NOT (u)-[:ACKNOWLEDGED|POSTED]->(p)
RETURN c, u, count(p)
This return for every church and members of this church, a number of unacknowledged posts, not posted by the member.
I submitted a similar bug report. This seems to be a problem starting with 3.3.6.
https://github.com/neo4j/neo4j/issues/11967
I'm just starting out with Neo4j, kicking the tyres if you will, but i'm getting a count I wasn't expecting.
I have a made a dummy database with 999 employees who have made expense claims (26901 - I know this is an odd number, I had a loop running inserting dummy expense claims using setInterval in javascript assigning random claims to random employees and I forgot to stop it :S :)).
Goal: I would like to know how many employees have made expense claims in my database.
I started with the following query:
MATCH (ex:EXPENSE)<-[:MADE_EXPENSE_CLAIM]-(employee:Employee)-[:WORKS_IN]->(:Department)
RETURN COUNT(employee)`
However, i'm getting 20211 as the result of my count, which seems a little high.
If I run the query a different way I get a result that makes more sense (918 as the result):
MATCH (n:Employee)-[:WORKS_IN]->(:Department)
WHERE (n)-[:MADE_EXPENSE_CLAIM]->()
RETURN COUNT(n)`
Can anyone tell me what my two queries are doing and which one (if any) is actually achieving my goal? If not can you please correct my query?
Your first query returns the total number of expense claims made by all employees in departments.
Your second query returns the number of employees in departments that have made expense claims.
To simply return the number of distinct employees that have made expense claims you could do something like this...
MATCH (ex:EXPENSE)<-[:MADE_EXPENSE_CLAIM]-(employee:Employee)
RETURN count(DISTINCT employee)
To see the number of expense claims per employee you could do something like this. The number of rows will be the number of distinct employees that have made expense claims. If MADE_EXPENSE_CLAIM only points to expenses you could save some overhead in your query by removing the label for the Expense nodes.
MATCH ()<-[:MADE_EXPENSE_CLAIM]-(employee:Employee)
RETURN employee.name, count(*)
This is an extremely simple question, but reading through the docs for the first time, I can't figure out how to construct this query. Let's say I have a graph that looks like:
and additionally each person has an age associated with them.
What CYPHER query will get me a list of John's age and all the ages of the entire friend tree of John?
What I've tried so far:
MATCH (start)-[:friend]>(others)
WHERE start.name="John"
RETURN start.age, others.age
This has several problems,
It only goes one one one friend deep and I'd like to go to all friends of John.
It doesn't return a list, but a series of (john.age, other.age).
So what you need is not only friend of john, but also friends of friends. So you need to tell neo4j to recursively go deep in the graph.
This query goes 2 level deep.
MATCH (john:Person { name:"John" })-[:friend *1..2]->(friend: Person)
RETURN friend.name, friend.age;
To go n nevel deep, don't put anything i.e. *1..
Oh and I also found this nice example in neo4j
So what does *1..2 here means:
* to denote that its a recursion.
1 to denote that do not include john itself i.e. is the start node. If you put 0 here, it will also include the John node itself.
.. to denote that go from this node till ...
2 denotes the level of recursion. Here you say to stop at level 2. i.e. dont go beyond steve. If you put nothing there, it will keep on going until it cannot find a node that "has" a friend relationship
Documentation for these types of query match is here and a similar answer here.
i have just started using Neo4j, and after creating the whole graph i'm trying to get all the nodes related to another one by a relatioship.
Match (n)-[Friendship_with]->({Name:"Gabriel"}) return n
That should give me the nodes that are friend of Gabriel, what i'm doing wrong?
I have used too this:
Match n-[r:Friendship_with]->n1 where n1.Name="Gabriel" return n
That give me some nodes, but some of then aren't directly related to Gabriel (for example, Maria is friend of Gabriel, she appears when i write that, but Alex who is friend of Maria and not from Gabriel, appear too)
This is weird.
Your query is correct.
I would suggest to check your data. Are you sure there isn't any direct connection between Alex and Gabriel ?
You could visualize your graph and see what is happening exactly in the neo4j browser. Just type a query with a bit more info like:
MATCH (n)-[f:Friendship_with]->(p {Name:"Gabriel"}) return n,f,p
and use the graph view to inspect your data.
EDIT:
As Pointed out by Michael, your first query is missing a colon in front of the specified relationship label "Friendship_with". So neo4j thinks it is a (rather long) variable name for your relationships, just as 'n' or 'n1'. It will thus retrieve anything that is connected to Gabriel without filtering by relationship label.
It doesn't explain though why you:
get the same results with the first and second query
get a 2nd degree relation as a result
so check your data anyway :)
You forgot the colon before :Friendship_with
Don't forget to provide labels, e.g. (n1:Person {Name:"Gabriel"})
Also some of your friendships might go in the other direction, so leave off the direction-arrow: Match (n:Person)-[Friendship_with]-(:Person {Name:"Gabriel"}) return n
I'm trying to query Book nodes for recommendation by Cypher.
I want to recommend A:Book and C:Book for A:User.
i'm sorry I need some graph to explain this question, but I could't up graph image because my lepletion lacks for upload function.
I wrote query below.
match (u1:User{uid:'1003'})-->(o1:Order)-->(b1:Book)<--(o2:Order)
<--(u2:User)-->(o3:Order)-->(b2:Book)
return b2
This query return all Books(A,B,C,D) dispite cypher's Uniqueness.
I expect to only return A:Book and C:Book.
Is this behavior Neo4j' specification?
How do I get expected return? Thanks, everyone.
environment:
Neo4j ver.v2.0.0-RC1
Using Neo4j Server with REST API
Without the sample graph its hard to say why you get something back when you expected something else. You can share a sample graph by including a create statement that would generate said graph, or by creating it in Neo4j console and putting the link in your question. Here is an example of the latter: console.neo4j.org/r/fnnz6b
In the meantime, you probably want to declare the type of the relationships in your pattern. If a :User has more than one type of outgoing relationships you will be excluding those other paths based on the labels of the nodes on the other end, which is much less efficient than to only traverse the right relationships to begin with.
To my mind its not clear whether (u:User)-->(o:Order)-->(b:Book) means that a user has one or more orders, and each order consists of one or more books; or if it means only that a user ordered a book. If you can share a sample, hopefully that will be clear too.
Edit:
Great, so looking at the graph: You get B and D back because others who bought B also bought D, and others who bought D also bought B, which is your criterion for recommendation. You can add a filter in the WHERE clause to exclude those books that the user has already bought, something like
WHERE NOT (u1)-[:BUY]->()-[:CONTAINS]->(b2)
This will give you A, C, C back, since there are two matching paths to C. It's probably not important to get two result items for C, so you can either limit the return to give only distinct values
RETURN DISTINCT(b2)
or group the return values by counting the matching paths for each result as a 'recommendation score'
RETURN b2, COUNT(b2) as score
Also, if each order only [CONTAINS] one book, you could try modelling without order, just (:User)-[:BOUGHT]->(:Book).