-
Notifications
You must be signed in to change notification settings - Fork 273
Neo4j::Core Lucene
Neo4j comes included with the lucene document database.
A common use case for using lucene is searching for one node and from that node traverse or use a cypher query.
The lucene integration uses the beforeCommit hook, see http://docs.neo4j.org/chunked/1.7/transactions-events.html. The method Neo4j::Node.trigger_on
is used to tell neo4j.rb which nodes or relationship it will index.
The Neo4j::Node.index
method is used to tell which properties are going to be index and which type of index should be used.
Example:
Neo4j::Node.trigger_on(:typex => 'MyTypeX')
Neo4j::Node.index :name
Neo4j::Node.index :description, :type => :fulltext
Neo4j::Node.index :age, :field_type => Fixnum
The declaration above will tell neo4j.rb that only nodes which have the property typex
value MyTypeX
will be indexed. When the before commit hook finds a node with that property it will index each property declared with the Neo4j::Node.index
method.
The default type of index being used is exact
. The example above declares index on property name
and description
with different types of indexes (exact and fulltext).
All values are indexed as Strings in lucene by default. If you want to index a value as a numeric value you can specify that with setting :field_type
to Fixnum or Float. By doing that allows you to use lucene range searches.
Notice, if you are using the Neo4j::NodeMixin
or Neo4j::Rails::
Model@ you define an index using the property
method instead.
Notice You can’t find using a String on none String field_types. Instead you must use hash queryes (e.g. Neo4j::Node.find(:age => 4) !
Instead of using the Neo4j::Node.index
or Neo4j::Relationship.index
methods you can define your own class for indexing. This allows you to have different lucene index files and configurations.
Example:
class MyIndex
extend Neo4j::Core::Index::ClassMethods
include Neo4j::Core::Index
self.node_indexer do
index_names :exact => 'myindex_exact', :fulltext => 'myindex_fulltext'
trigger_on :myindex => true # trigger on all nodes having property myindex == true
end
index :name
end
This class is also used when searching, e.g. MyIndex.find(:name => 'andreas').first
For index on relationship use the rel_indexer
method instead of the node_indexer
method.
You can use the lucene query language
Let say you have defined the index on the Neo4j::Node class like this:
Neo4j::Node.trigger_on(:typex => 'MyTypeX')
Neo4j::Node.index(:name)
And you have created a node like this:
a = Neo4j::Node.new(:name => 'andreas', :typex => 'MyTypeX')
Then you can find it using the lucene query syntax like this:
Neo4j::Node.find(:name => 'andreas') {|result| puts result.first[:name] }
# or same if this if you want to close the lucene connection yourself
result = Neo4j::Node.find(:name => 'andreas')
puts result.first[:name]
result.close
Notice It is important that you close the lucene connection. Either use the block approach or call the close method on the query result.
Notice The Neo4j::Rails::Model.find
and Neo4j::Rails::Relationship.find
methods does close the lucene connection automatically using a Rack.
A property in neo4j can be an array of (primitive) values.
Lucene does also support searching in arrays of values.
Example:
# don't forget declare index on things: Neo4j::Node.index :things
Neo4j::Transaction.new do
Neo4j::Node.new(:things => ['aaa', 'bbb', 'ccc'])
end
Neo4j::Node.find("things: bbb"){|r| puts r.first}
You can also search with an array of values. Example let find a node with property :things
having value "bbb"
or "ccc"
:
Neo4j::Node.find(:things => ["bbb", "ccc"]){|r| puts r.first}
The search will result in an OR lucene search for that property.
By using a hash instead of String inj the find method you can search on several properties at once (a compound AND lucene query).
MyIndex.find(:name => 'asd').or(:wheels => 8).first.should == thing3
You can make compound queries using the and
or
and not
method on the query result.
Example
MyIndex.find(:name => 'asd').or(:wheels => 8).first.should == thing3
If you want to do a numerical range search you must declare the index field_type
to Fixnum or Float
For Neo4j::Rails::Model
and Neo4j::NodeMixin
you do that with the :type
config on the property
instead of using the field_type
on the index
method.
There are two ways of doing range search – using the between method or using the Ruby Range class.
Example, using between
MyIndex.find(:age).between(2, 5)
Example, using the Ruby Range class:
MyIndex.find(:name => 'thing').and(:wheels => (9..15)).should be_empty
Notice Range queries on none String (e.g. :field_type
=> Fixnum) is not possible using a String lucene query, instead you must use a hash query, as shown above.
Use the asc
or desc
method on the query result, example:
MyIndex.find('name: *@gmail.com').asc(:name).desc(:age)
Notice you must have an index on the sorted fields.
WARNING: Much of the information in this wiki is out of date. We are in the process of moving things to readthedocs
- Project Introduction
- Neo4j::ActiveNode
- Neo4j::ActiveRel
- Search and Scope
- Validation, Uniqueness, and Case Sensitivity
- Indexing VS Legacy Indexing
- Optimized Methods
- Inheritance
- Core: Nodes & Rels
- Introduction
- Persistence
- Find : Lucene
- Relationships
- Third Party Gems & extensions
- Scaffolding & Generators
- HA Cluster