neo4j: Creating a Custom Index With neo4j.rb
Join the DZone community and get the full member experience.
Join For FreeAs I mentioned in my last post, I’ve been playing around with the TFL Bus stop location and routes API. One thing I wanted to do was load all the bus stops into a neo4j database using the neo4j.rb gem.
I initially populated the database via neography, but it was taking around 20 minutes per run, and I figured it’d probably be much quicker to populate it directly rather than using the REST API.
Creating nodes is reasonably simple, and the code to add bus stops looks like this:
require 'neo4j' Neo4j::Transaction.run do stops_to_add = [ {:name => "Walworth Road", :code => 10001 }] stops_to_add.each do |stop| node = Neo4j::Node.new(:name => stop[:name], :code => stop[:code], :type => "stop") puts "Code: #{stop[:code]}, Stop: #{stop[:name]}" end end
I wanted to be able to search for bus stops using cypher, so I needed
to create an index for each stop to allow me to do that easily.
I initially tried creating a Stop class and defining the index in there, as suggested in the documentation, but from what I could tell it created an index named after the string representation of the Stop object, making it difficult to use in cypher.
Eventually I came across another page that said I needed to create a ‘custom index’ if I wanted to be able to reference it by name.
I ended up with the following:
class StopsIndex extend Neo4j::Core::Index::ClassMethods include Neo4j::Core::Index self.node_indexer do index_names :exact => 'stops' trigger_on :type => "stop" end index :code end
As far as I understand, this index gets triggered when you’re inside a
transaction while adding a node of type ‘stop’, which is what I’m doing here.
With the index defined this way, it’s now possible to look up stops using cypher:
START stop = node:stops(code = "10001") RETURN stop
And later, when I wanted to add a ‘route’ between stops in the code, I could look up the stops like so:
Neo4j::Transaction.run do stop1 = StopsIndex.find("code: \"10001\"").first stop2 = StopsIndex.find("code: \"10002\"").first Neo4j::Relationship.new(:route, stop1, stop2, { :bus_number => 1 }) end
The full code for this is on github.
Published at DZone with permission of Mark Needham, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Multi-Stream Joins With SQL
-
You’ve Got Mail… and It’s a SPAM!
-
What Is JHipster?
-
Developers Are Scaling Faster Than Ever: Here’s How Security Can Keep Up
Comments