cancel
Showing results for 
Search instead for 
Did you mean: 

Join the community at Nodes 2022, our free virtual event on November 16 - 17.

How to search according to relationship

Hi, 

I have a data like this in csv file:

fn,ln,city

A,F,C

B,F,D

C,F,E

H,Z,E

 

And i created graph like this:

LOAD CSV WITH HEADERS FROM "file:///test_data1.csv" as col

MERGE (FN:Firstname{name:col.`fn`})

MERGE (LN:Lastname{name:col.`ln`})

MERGE (CITY:City{name:col.`city`})
MERGE (FN)-[:HAS_LASTNAME]->(LN)
MERGE (LN)-[:LIVES_IN]->(CITY)

Now i want city name for firstaname A.
How can i do this?

I wrote this query.

MATCH (a:Firstname)-[:HAS_LASTNAME]->(b:Lastname)-[:LIVES_IN]->(c:City)

where a.name ="A" and b.name = "F"

RETURN c.name

but not getting right result.

Thank you.

17 REPLIES 17

glilienfield
Ninja
Ninja

I reproduced your data and I received three rows back from the query.  The reason there are three is because lastname 'F' lives in three cities: 'C', 'D', and 'E'

Screen Shot 2022-08-03 at 12.52.39 PM.png

Screen Shot 2022-08-03 at 12.53.36 PM.png

Screen Shot 2022-08-03 at 12.53.57 PM.png

Hi @glilienfield
Yes, I  am getting the same result with three cities name C, D, E. 
But the correct result will be only C, as i want the city for only FN 'A'. 
How can i do this?
Could you please help me in this?

Also, I do not want to create duplicate nodes for any column. 

Thanks in advance. 

Your data model does not support that. The query pattern you are using specifies any path between first name, last name, and city, where you restrict the first name and last name. From the data, you can see that there are three paths that satisfy this criteria. The data model does not indicate which city is associated with a pair of first names and last names. You would need to associated the first name to the city two, so that the combination of first name and last name is related to a single city.  Of course, if you have multiple with that live in different cities but have the same combination of first name and last name, you will again have an issue. 

What is your use case that you are trying to track the first name and last name separately, versus having a Person entity that has the person's first name, last name, and other properties of the person stored with the Person node?

Screen Shot 2022-08-03 at 1.07.27 PM.png

Hi, 
I have a data with person properties firstname, lastname etc, and i am creating graph with each property has a different node not all the properties to a single node. 
My objective is to apply optimised search. 

Thank you. 

I just want the queries like given a column name, i can find other other properties. 

 

steggy
Neo4j
Neo4j

@lokeshgupta1212 is there a reason you modeled your data in this way? Your data model will break down. Say you have a john smith who lives in chicago and a dave smith who lives in boston. you have both john and dave having last name smith, and smith lives in both boston and chicago. @glilienfields suggestion seems to be the right one - model a person node with properties for first name and last name. 

Hi @steggy , 
There are two reason to create this data model:
1. For optimized/fast search. 
2. To look data fancy. 

Please help, if you have any idea, without keeping two properties in a single node. I want property in one node. 

Thank you. 

 

steggy
Neo4j
Neo4j

Well, I'll ignore #2. We don't design databases to look nice, we design them to solve problems 🙂 

If you're just trying to understand how you might do this... what you need is not to have a unique first name and last name node for each person, not share nodes with common first or last names. This is still more an academic exercise though. Have you tried a single node with first name and last name properties (and perhaps approrpiate indexes, depending on your query) to see what kind of performance you get?

Hi @steggy 
2 point means, understand the data clearly. 

Thank you. 

ameyasoft
Graph Maven

Following @steggy , add fname and lname properties to City node

LOAD CSV WITH HEADERS FROM "file:///test_data1.csv" as col
MERGE (FN:Firstname{name:col.`fn`})
MERGE (LN:Lastname{name:col.`ln`})
MERGE (CITY:City{name:col.`city`, fname:col.`fn`, lname:col.`ln` })
MERGE (FN)-[:HAS_LASTNAME]->(LN)
MERGE (LN)-[:LIVES_IN]->(CITY)


MATCH (a:Firstname)-[:HAS_LASTNAME]->(b:Lastname)-[:LIVES_IN]->(c:City)
where a.name ="A" and b.name = "F" and c.fname = a.name and c.lname = b.name

In your proposed model, the city is now specific to users with the same first and last name. It seems the model that makes the most sense is to have a Person node with first name, last name, and a unique identifier, which is linked to a city node. 

Yes, it's best provided a unique identifier exists.

Hi @glilienfield 
I do not want to break the property of graph theory, if there are two nodes with name "E", in my our graph it must be only one and then, I want the desired result. 

Thank you for keep posting suggestion. 

Hi @ameyasoft , 
If I go with your solution, then city node "E", will be 2, although they have different properties, 
but i need unique nodes i.e. it must be only one node "E". 

ameyasoft
Graph Maven

Other option is to add fname and lname  properties to LIVES_IN relationship:

LOAD CSV WITH HEADERS FROM "file:///test_data1.csv" as col
MERGE (FN:Firstname{name:col.`fn`})
MERGE (LN:Lastname{name:col.`ln`})
MERGE (CITY:City{name:col.`city`})
MERGE (FN)-[:HAS_LASTNAME]->(LN)
MERGE (LN)-[:LIVES_IN {fname:col.`fn`, lname:col.`ln`}]->(CITY)

MATCH (a:Firstname)-[:HAS_LASTNAME]->(b:Lastname)-[r:LIVES_IN]->(c:City)
where a.name ="A" and b.name = "F" and r.fname = a.name and r.lname = b.name
If you have a UserID then use userid as one property of LIVES_IN relationship.

steggy
Neo4j
Neo4j

All of the alternative data models here seem to be more of an academic interest than otherwise. @lokeshgupta1212 have you tested the simple model (Person with fn, ln properties), and have you identified a problem with that model? Models are designed to be able to answer the questions you ask of the data in a performant way, and unless I'm missing something, I think the simple model meets the requirements (can answer the question), and is easy to understand. Are there other queries you're thinking about that are driving this question?

If there's some reason you're trying to break out first name and last name into separate nodes, why not something like:

LOAD CSV WITH HEADERS FROM "file:///test_data1.csv" as col
MERGE (FN:Firstname{name:col.`fn`})
MERGE (LN:Lastname{name:col.`ln`})
MERGE (p:Person {fn:col.`fn`, ln:col.`ln`})
MERGE (p)-[:HAS_FIRSTNAME]->(FN)
MERGE (p)-[:HAS_LASTNAME]->(LN)
MERGE (CITY:City{name:col.`city`})
MERGE (p)-[:LIVES_IN]->(CITY)

Then

MATCH (Firstname {name: 'A'})<-[:HAS_FIRSTNAME]-(p:Person)
MATCH (Lastname {name: 'F'})<-[:HAS_LASTNAME]-(p:Person)-[:LIVES_IN]->(c:City)
RETURN c.name

But this seems like overkill to me. Back to my original question: is there a problem you've identified with the simple (Person)-[:LIVES_IN]->(City) model?

J