-
Notifications
You must be signed in to change notification settings - Fork 276
Neo4j::Rails Lucene
You can use Lucene to find nodes. A common use case is to find one or more nodes/relationship and then traverse from them (using the Traversal methods or a Cypher Query).
See also Neo4j::Core-Cypher, Neo4j::Wrapper-Rules-and-Functions and Neo4j::Core-Traverse for alternative of finding nodes and relationships.
Neo4j also supports the orm_adaptor API which can be used for searching.
You use the Neo4j::Rails::Model#property
and Neo4j::Rails::Relationship#property
to declare lucene index (same as for Neo4j::NodeMixin, see Neo4j::Wrapper-Lucene
Example:
class Role < Neo4j::Rails::Relationship
property :since, :type => Fixnum, :index => :exact
end
Notice for the unique validations and unique entities (e.g. Neo4j::Rails::Model.get_or_create
) method to work you must declare an index, see Neo4j::Rails-Persistence.
The find
and all
methods use the model’s Lucene index to search for either one or a set of nodes respectively. Make sure to index the properties that you’ll query on.
Notice 2 If you don’t declare the index it will try to use cypher to perform the query (this since neo4j version 2.2)
Another example:
class IceCream < Neo4j::Model
property :flavour, :index => :exact
property :cone, :index => :exact
end
See Neo4j::Wrapper-Lucene and Neo4j::Core-Lucene for more documentation how to declare and use a lucene index.
The Neo4j::Rails::Model.find
and Neo4j::Rails::Relationship.find
method behaves different compared to Neo4j::Node.find
and Neo4j::NodeMixin.find
.
The find
method will find the first node that matches its query or nil
if one isn’t found.
Example:
IceCream.find('cone: sugar') #=> vanilla_sugar
IceCream.find('flavour: vanilla') #=> who knows?
IceCream.find(:flavour => 'vanilla') #=> same as above
IceCream.find('flavour: chocolate') #=> nil
The find
method will also accept a Neo4j node id which is useful for finding a node in a rails controller.
class IceCreamController < ApplicationController
def show
@ice_cream = IceCream.find(params[:id])
# . . .
end
end
The Neo4j::Model also support Active Record like query syntax:
Model.find(:first, :conditions => { :name => "test" }) # works the same as find("name: \"test\"")
Model.find(:first, :conditions => { :id => 10 }) # works the same as find(10) or find("10")
It does also generate finder methods like IceCream.find_by_flavour
or find_or_create_by_flavour
, see below.
The all
method will find a set of nodes or relationship. If none is find it will return an empty array.
Some examples:
IceCream.all #=> [vanilla_sugar, vanilla_waffle]
IceCream.all('flavour: vanilla') #=> [vanilla_sugar, vanilla_waffle]
IceCream.all('flavour: vanilla AND cone: sugar') #=> [vanilla_sugar]
IceCream.all('flavour: chocolate') #=> []
IceCream.all(:flavour => 'chocolate')
IceCream.find(:all, :conditions => {:flavour => 'chocolate'}, :sort => {:name => :asc})
IceCream.find(:all, 'name: choclate').asc(:name)
Tip: String parameter values with special characters, such as URI’s, should be escaped first before setting or querying to not conflict with the Lucene Query Parser Syntax: + – && || ! ( ) { } ^ " ~ * ? : \ . See Apache Lucene – Query Parser Syntax
escaped = URI.escape( "http://neo4j.rubyforge.org/guides", Regexp.new( "[^#{URI::PATTERN::UNRESERVED}]" ))
Website.find("uri: #{escaped}")
TIP: The find methods (e.g. all
) also work for subclasses for Neo4j::Rails::Model (but as expected for subclasses of Neo4j::Rails::Relationship).
An example of using the lucene full text search index:
class BlogEntry < Neo4j::Rails::Model
property :text, :index => :fulltext
end
e = BlogEntry.create(:text => 'some long text string')
BlogEntry.find('text: long', :type => :fulltext) #=> e
BlogEntry.all('text: long', :type => :fulltext).size #=> 1
Notice that you need to specify the :fulltext
configuration property for both declaring the index and searching.
You can use Lucene syntax as described here with a fulltext query for more power.
BlogEntry.find(:first, 'text: "some string"~2', type: :fulltext) #=> e
BlogEntry.find(:first, 'text: zome~', type: :fulltext) #=> e
BlogEntry.find(:all, 'text: s?me', type: :fulltext).count #=> 1
If you declare an index you neo4j.rb will generate finder methods for you.
Example:
class Person
property :name
index :name
end
Person.find_by_name 'andreas' # with underscore of course, not visible
For a complete list of available methods see Neo4j::Rails::Finders
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