MohanVS
MohanVS

Reputation: 167

No nodes added to index in Neo4j

The query I used to create the nodes is as follows

load csv with headers from "file:/sample.csv" as Jobs
create (TheJobs {Job_name: Jobs.insert_job, Job_type: Jobs.job_type, Owner: Jobs.#owner}) 
return TheJobs

and the command I used to create index was

CREATE INDEX ON :TheJobs(Job_name)

Output: Added 1 index, statement executed in 32 ms.

Then I tried to create relationships using the following query

Profile load csv with headers from "file:/Jobstofiles.csv" 
as rels2 
match (from :Files {Filename: rels2.Filename}) 
where rels2.Automatic or Manual="Automatic"
match (to :TheJobs {Job_name: rels2.Job}) 
create (from)-[:Is_triggered_by {type: rels2.Is_triggered_by}]->(to) 
return from, to 

The execution plan shows nodeindexseek, but returns zero rows/matches when the data clearly matches

When I try to search a node from the index using the following query

PROFILE MATCH (node :Jobindex {Job_name: 'Job1'}) RETURN node

Output: 0 rows

What am I doing wrong?

Upvotes: 0

Views: 178

Answers (1)

InverseFalcon
InverseFalcon

Reputation: 30397

I think you may have misread how indexes are used in neo4j.

Your creation of the index:

CREATE INDEX ON :Jobindex(Job_name)

does not create an index called Jobindex on the Job_name property of all nodes, that's not how it works.

Instead, what you did was create an index on the Job_name property of nodes with the :Jobindex label. Meaning that this index is only used when you have a :Jobindex node with a Job_name property.

If you need to index on the Job_name property on a different kind of node, create an index with the label of that node. If you want to index on that property across nodes with differing labels, then consider if there is some more universal label you can apply to those nodes and then index on that (remember that nodes can have multiple labels).

As for using indexes, though there are ways to force usage of an index, these aren't common cases. Index usage is largely invisible to you, there is no special syntax for it, just write your match using the property that happens to be indexed, and the index will be used under the hood (if present) to speed up the lookup.

In other words, if you indexed on :Job(Job_name), and you wanted to look up a job by name, you'd query it with:

MATCH (job:Job{Job_name:"Software Engineer"})
...

Which is exactly how you would query it without an index.

I'd suggest rereading the Schema section of the Cypher manual.

EDIT: Adding examples.

So, let's say that in the data you are importing, you expect to create nodes with the :Job label, which will have the Job_name property for fast lookup by name.

You'll want to create your index like this:

CREATE INDEX ON :Job(Job_name)

That way any operation that explicitly uses a :Job node and its Job_name property will take advantage of that index to improve the lookup speed, if possible.

But if you have a different case, needing to do the indexing over different kinds of nodes that have that same property, you still need a common label for that index. If this is just for data import, then you might cheat a bit, and create nodes with multiple labels, where one of those labels is the one you created an index on. Then, when you're done with your import, you can delete the index if it's not of any more use to you.

Upvotes: 1

Related Questions