neo4j, how can search for relationship in this example? - neo4j

I was learning neo4j, and following the tutorial provide atsearching for relationship.
I followed it, added two nodes and a relationship between them. I did exactly according to the tutorial in above link. But when i try to display the relationship i just added, by the following
MATCH (e)-[r:DO_SHOPPING_WITH ]->(cc)
RETURN r
it showed nothing.
to make sure, I displayed all nodes by
MATCH (a) return a
and it showed 2 nodes and the relationship between them.
Not only this case, I tried later examples, by similar search for relationship all are showed empty.
could anyone explain why I cannot display the relationship as it is told in the tutorial?
Pretty simple example, but somehow not working.
Please help!

It sounds like you're just talking about the graph result view. When the only items returned from a query are relationships, they won't show up, as it requires the nodes on either side of a relationship to be returned in order to display.
While this is current behavior, past behavior was able to display the start and end nodes of a relationship even if just relationships were returned, and it's not a bad idea to consider reverting to this previous behavior.
I think this issue on the browser project is related.

Related

Kevin path at neo4j

I am trying to discover how many hops I have to do to know a friend with Cipher. I have these relationships.
(Gutierrez)-[:Conhece]->(Felipe),
(Felipe)-[:Conhece]->(Gutierrez),
(Felipe)-[:Conhece]->(Fernando),
(Fernando)-[:Conhece]->(Felipe),
(Fernando)-[:Conhece]->(Pedro),
(Pedro)-[:Conhece]->(Fernando),
(Pedro)-[:Conhece]->(Arthur),
(Arthur)-[:Conhece]->(Pedro),
(Arthur)-[:Conhece]->(Vitor),
(Vitor)-[:Conhece]->(Arthur),
and when I execute my query it shows Fernando. What I want is to show only Vitor, Pedro and Arthur.
MATCH (n:Leitor)-[r:Conhece]-m
WHERE n.nome='Pedro' OR m.nome='Vitor'
RETURN n,r,m
with my Bacon Path query ->
Ok, I'm adding another answer because I think I understand what you want and it's different than my other answer.
If you want to find everybody that both Pedro and Vitor have met (in this case, just Author):
MATCH (pedro:Leitor)-[:Conhece]-(in_common:Leitor)-[:Conhece]-(vitor:Leitor)
WHERE pedro.nome='Pedro' AND vitor.nome='Vitor'
RETURN in_common
That also might look a bit better like this:
MATCH (pedro:Leitor {nome: 'Pedro'})-[:Conhece]-(in_common:Leitor)-[:Conhece]-(vitor:Leitor {name: 'Vitor'})
RETURN in_common
I also notice from your screenshots that every meeting has two relationships. That may very well be what you want, but if your plan was to always have two relationships whenever two people meet then you can get away with just one relationship. When you query bidirectionally (that is, without specifying direction like in the queries above) then you'll get relationships in either direction.
Normally you only want relationships going in both directions if the direction is important. That could be because your just recording that it goes from one node to another, or it could be because you're storing different values on the relationships.
Here you go:
MATCH shortestPath((n:Leitor)-[rels:Conhece*]-m)
WHERE n.nome IN ['Pedro', 'Vitor']
RETURN n,rels,m,length(rels)
In this case rels will be a collection of relationships because the path is variable length. You can also do:
MATCH path=shortestPath((n:Leitor)-[rels:Conhece*]-m)
WHERE n.nome IN ['Pedro', 'Vitor']
RETURN n,rels,m,length(rels),path,length(path)

Return Nodes related with a relatiohip to other Neo4j

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

"Ordered lists" and bi- vs. uni-directional relationships

I'm a Neo4j newbie, just playing around in the browser modelling data for a project at the moment.
Here's my use case: A user can have a bunch of items. Each item is described by a storyline.
(:User)-[:OWNS]->(:Item)<-[:DESCRIBES]-(:Storyline)
No issues so far. However, the storyline needs to contain "cards", basically chapters of the story that need to be in order. So, my first thought was this.
(:Storyline)<-[:FOLLOWS]<-(a:Card)<-[:FOLLOWS]-(b:Card)
However, if we start at Card B, we now have to follow the path back to see what storyline/item the card belongs to. Seems inefficient. Would it be better to do this?
(a:Card {order: 0})-[:BELONGS_TO]->(:Storyline)
(b:Card {order: 1})-[:BELONGS_TO]->(:Storyline)
Or, might I even trash the Storyline and just have the following?
(:Card {order:0})-[:DESCRIBES]->(:Item)
Next, a user should be free to create a link to another storyline card belonging to his own or any other user's item.
(storyA:Card)-[:LINKS_TO]->(storyB:Card)
However, the owner of storyB may or may not want to link back to the first guy's story. I know you can ignore the direction of the relationship in a cypher query by doing:
(a)-[r]-(b)
But I read that explicitly creating bi-directional relationships is usually a bad idea. So if storyB wants to link back, how would you best represent this in the data model? Maybe another relationship type, like :LINKS_MUTUALLY or something, or a "mutual" boolean property on the :LINKS_TO relationship?
Regarding you first issue, it's usually better to have relationships rather than properties in this case.
I'd throw in FIRST and LAST relationships, like in this TimeTree, and model it as:
(a:Card)-[:DESCRIBES]->(i:Item)
(b:Card)-[:DESCRIBES]->(i:Item)
(c:Card)-[:DESCRIBES]->(i:Item)
(a:Card)<-[:FOLLOWS]-(b:Card)
(b:Card)<-[:FOLLOWS]-(c:Card)
(a:Card)<-[:FIRST_CARD]-(i:Item) //optional, for easy navigation
(c:Card)<-[:LAST_CARD]-(i:Item) //optional, for easy navigation
As for bidirectional relationships, the only are a bad idea if a relationship in one direction implies the other one. In your case, this is not the case, so creating (storyA:Card)-[:LINKS_TO]->(storyB:Card) and (storyA:Card)<-[:LINKS_TO]-(storyB:Card) is perfectly fine, since each relationship is there for a different reason.

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

Returning all relationships for a list of nodes

This is quite a general question but to make it more understandable I'll give it a bit of context.
In neo4j I have a series of words (nodes) that are associated with one another. I want to specify a list of nodes and the Cypher query return a list of any relationships between those nodes.
The nodes specified in the list are all guaranteed to have at least one relationship to another node specified in the list.
I created a query to do this and in certain circumstances it works fine - http://console.neo4j.org/?id=s30cbm
Unfortunately, when I add the words 'bark' and 'dog' to the list I get an 'unexpected traversal state encountered' error message. I presume this is because the database cursor has got to the fruit node and then there's no relationship between that and bark, even though there is a relationship from tree to bark. http://console.neo4j.org/?id=258d6g
I'm obviously doing the query slightly wrong and any advice would be appreciated on how I can rectify this.
This works in the latest console (your second link), btw, so it looks like they fixed it. Looks like it should be working in 1.9-M04+.

Resources