neo4j 1.0.0.beta.17 → 1.0.0.beta.18
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -2
- data/README.rdoc +2 -2
- data/lib/generators/neo4j.rb +65 -0
- data/lib/generators/neo4j/model/model_generator.rb +39 -0
- data/lib/generators/neo4j/model/templates/model.rb +7 -0
- data/lib/neo4j.rb +2 -2
- data/lib/neo4j/config.rb +14 -12
- data/lib/neo4j/database.rb +1 -1
- data/lib/neo4j/equal.rb +3 -0
- data/lib/neo4j/event_handler.rb +25 -14
- data/lib/neo4j/index/class_methods.rb +3 -2
- data/lib/neo4j/index/indexer.rb +121 -21
- data/lib/neo4j/index/lucene_query.rb +156 -0
- data/lib/neo4j/load.rb +3 -2
- data/lib/neo4j/mapping/class_methods/property.rb +16 -0
- data/lib/neo4j/mapping/class_methods/relationship.rb +3 -1
- data/lib/neo4j/mapping/class_methods/root.rb +3 -0
- data/lib/neo4j/mapping/class_methods/rule.rb +141 -66
- data/lib/neo4j/mapping/decl_relationship_dsl.rb +8 -8
- data/lib/neo4j/mapping/has_n.rb +11 -1
- data/lib/neo4j/mapping/node_mixin.rb +20 -0
- data/lib/neo4j/neo4j.rb +24 -5
- data/lib/neo4j/node.rb +1 -1
- data/lib/neo4j/property.rb +1 -1
- data/lib/neo4j/rails/model.rb +40 -36
- data/lib/neo4j/rails/properties.rb +29 -0
- data/lib/neo4j/rails/value.rb +8 -29
- data/lib/neo4j/transaction.rb +0 -1
- data/lib/neo4j/version.rb +1 -1
- metadata +8 -5
- data/lib/neo4j/index/wrapped_query.rb +0 -59
- data/lib/neo4j/mapping/class_methods/index.rb +0 -17
data/Gemfile
CHANGED
@@ -6,11 +6,11 @@ group 'test' do
|
|
6
6
|
gem "rake", ">= 0.8.7"
|
7
7
|
gem "rdoc", ">= 2.5.10"
|
8
8
|
gem "horo", ">= 1.0.2"
|
9
|
-
gem "rspec-apigen", ">= 0.0.4"
|
10
9
|
gem "rspec", ">= 2.0.0"
|
11
10
|
gem "rspec-rails-matchers", ">= 0.2.1"
|
11
|
+
gem "test-unit"
|
12
12
|
end
|
13
13
|
|
14
14
|
gem 'ruby-debug-base19' if RUBY_VERSION.include? "1.9"
|
15
15
|
gem 'ruby-debug-base' if RUBY_VERSION.include? "1.8"
|
16
|
-
gem "ruby-debug-ide"
|
16
|
+
gem "ruby-debug-ide"
|
data/README.rdoc
CHANGED
@@ -15,13 +15,13 @@ Here are some of the major benefits of Neo4j.rb
|
|
15
15
|
|
16
16
|
* Domain Modeling - use the language of a graph (nodes/relationship/properties) to express your domain !
|
17
17
|
* Schema Less and Efficient storage of Semi Structured Information
|
18
|
-
* No {O/R mismatch}[http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch] - very natural to map a graph to an Object Oriented language like Ruby.
|
18
|
+
* No {O/R mismatch}[http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch] - very natural to map a graph to an \Object Oriented language like Ruby.
|
19
19
|
* {Performance}[http://www.oscon.com/oscon2009/public/schedule/detail/8364]
|
20
20
|
* Embedded Database - no database tier, easier to install, test, deploy and configure. It is run in the same process as your application.
|
21
21
|
* Express Queries as Traversals
|
22
22
|
* Fast deep traversal instead of slow SQL queries that span many table joins.
|
23
23
|
* Very natural to express graph related problem with traversals (recommendation engine, find shortest parth etc..)
|
24
|
-
* Seamless integration with Ruby on Rails.
|
24
|
+
* Seamless integration with Ruby on \Rails.
|
25
25
|
* ACID Transaction with rollbacks support.
|
26
26
|
|
27
27
|
=== Documentation
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'rails/generators/named_base'
|
2
|
+
require 'rails/generators/active_model'
|
3
|
+
|
4
|
+
module Neo4j
|
5
|
+
module Generators
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Neo4j::Generators::Base < Rails::Generators::NamedBase #:nodoc:
|
10
|
+
def self.source_root
|
11
|
+
@_neo4j_source_root ||= File.expand_path(File.join(File.dirname(__FILE__),
|
12
|
+
'neo4j', generator_name, 'templates'))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Neo4j::Generators::ActiveModel < Rails::Generators::ActiveModel #:nodoc:
|
17
|
+
def self.all(klass)
|
18
|
+
"#{klass}.all"
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.find(klass, params=nil)
|
22
|
+
"#{klass}.find(#{params})"
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.build(klass, params=nil)
|
26
|
+
if params
|
27
|
+
"#{klass}.new(#{params})"
|
28
|
+
else
|
29
|
+
"#{klass}.new"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def save
|
34
|
+
"#{name}.save"
|
35
|
+
end
|
36
|
+
|
37
|
+
def update_attributes(params=nil)
|
38
|
+
"#{name}.update_attributes(#{params})"
|
39
|
+
end
|
40
|
+
|
41
|
+
def errors
|
42
|
+
"#{name}.errors"
|
43
|
+
end
|
44
|
+
|
45
|
+
def destroy
|
46
|
+
"#{name}.destroy"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module Rails
|
51
|
+
module Generators
|
52
|
+
class GeneratedAttribute #:nodoc:
|
53
|
+
def type_class
|
54
|
+
case type.to_s.downcase
|
55
|
+
when 'datetime' then 'DateTime'
|
56
|
+
when 'date' then 'Date'
|
57
|
+
when 'text' then 'String'
|
58
|
+
when 'integer', 'number', 'fixnum' then 'Fixnum'
|
59
|
+
when 'float' then 'Float'
|
60
|
+
else 'String'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'neo4j.rb')
|
2
|
+
|
3
|
+
class Neo4j::Generators::ModelGenerator < Neo4j::Generators::Base
|
4
|
+
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
5
|
+
|
6
|
+
check_class_collision
|
7
|
+
|
8
|
+
class_option :timestamps, :type => :boolean
|
9
|
+
class_option :parent, :type => :string, :desc => "The parent class for the generated model"
|
10
|
+
|
11
|
+
def create_model_file
|
12
|
+
template "model.rb", File.join('app/models', "#{singular_name}.rb")
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
def migration?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def timestamps?
|
21
|
+
options[:timestamps]
|
22
|
+
end
|
23
|
+
|
24
|
+
def parent?
|
25
|
+
options[:parent]
|
26
|
+
end
|
27
|
+
|
28
|
+
def timestamp_statements
|
29
|
+
%q{
|
30
|
+
property :created_at, DateTime
|
31
|
+
# property :created_on, Date
|
32
|
+
|
33
|
+
property :updated_at, DateTime
|
34
|
+
# property :updated_on, Date
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
hook_for :test_framework
|
39
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
class <%= class_name %> < <%= parent? ? options[:parent].classify : "Neo4j::Rails::Model" %>
|
2
|
+
<% attributes.each do |attribute| -%>
|
3
|
+
property :<%= attribute.name %><%= ", :type => #{attribute.type_class}" unless attribute.type_class == "String" %>
|
4
|
+
<% end -%>
|
5
|
+
|
6
|
+
<%= timestamp_statements if timestamps? -%>
|
7
|
+
end
|
data/lib/neo4j.rb
CHANGED
@@ -22,7 +22,7 @@ require 'neo4j/index/index'
|
|
22
22
|
require 'neo4j/index/class_methods'
|
23
23
|
require 'neo4j/index/index_registry'
|
24
24
|
require 'neo4j/index/indexer'
|
25
|
-
require 'neo4j/index/
|
25
|
+
require 'neo4j/index/lucene_query'
|
26
26
|
require 'neo4j/relationship_traverser'
|
27
27
|
require 'neo4j/node_traverser'
|
28
28
|
require 'neo4j/property'
|
@@ -36,7 +36,6 @@ require 'neo4j/mapping/class_methods/init_node'
|
|
36
36
|
require 'neo4j/mapping/class_methods/init_rel'
|
37
37
|
require 'neo4j/mapping/class_methods/root'
|
38
38
|
require 'neo4j/mapping/class_methods/property'
|
39
|
-
require 'neo4j/mapping/class_methods/index'
|
40
39
|
require 'neo4j/mapping/class_methods/relationship'
|
41
40
|
require 'neo4j/mapping/decl_relationship_dsl'
|
42
41
|
require 'neo4j/mapping/has_n'
|
@@ -54,6 +53,7 @@ require 'neo4j/rails/transaction'
|
|
54
53
|
require 'neo4j/rails/railtie'
|
55
54
|
require 'neo4j/rails/validations/uniqueness'
|
56
55
|
require 'neo4j/rails/model'
|
56
|
+
require 'neo4j/rails/properties'
|
57
57
|
require 'neo4j/rails/value'
|
58
58
|
require 'neo4j/rails/lucene_connection_closer'
|
59
59
|
|
data/lib/neo4j/config.rb
CHANGED
@@ -2,9 +2,12 @@
|
|
2
2
|
module Neo4j
|
3
3
|
|
4
4
|
|
5
|
-
# Keeps configuration for neo4j.
|
5
|
+
# == Keeps configuration for neo4j.
|
6
6
|
#
|
7
|
-
# Neo4j::Config[:storage_path]
|
7
|
+
# The most important configuration is <tt>Neo4j::Config[:storage_path]</tt> which is used to
|
8
|
+
# locate where the neo4j database is stored on the filesystem.
|
9
|
+
# If this directory is empty then a new database will be created, otherwise it will use the
|
10
|
+
# database from that directory.
|
8
11
|
#
|
9
12
|
class Config
|
10
13
|
# This code is copied from merb-core/config.rb.
|
@@ -45,8 +48,8 @@ module Neo4j
|
|
45
48
|
# Set the value of a config entry.
|
46
49
|
#
|
47
50
|
# ==== Parameters
|
48
|
-
# key
|
49
|
-
# val
|
51
|
+
# key:: The key to set the parameter for.
|
52
|
+
# val:: The value of the parameter.
|
50
53
|
#
|
51
54
|
def []=(key, val)
|
52
55
|
(@configuration ||= setup)[key] = val
|
@@ -56,7 +59,7 @@ module Neo4j
|
|
56
59
|
# Gets the the value of a config entry
|
57
60
|
#
|
58
61
|
# ==== Parameters
|
59
|
-
# key
|
62
|
+
# key:: The key of the config entry value we want
|
60
63
|
#
|
61
64
|
def [](key)
|
62
65
|
(@configuration ||= setup)[key]
|
@@ -69,7 +72,7 @@ module Neo4j
|
|
69
72
|
# key<Object>:: The key of the parameter to delete.
|
70
73
|
#
|
71
74
|
# ==== Returns
|
72
|
-
#
|
75
|
+
# The value of the removed entry.
|
73
76
|
#
|
74
77
|
def delete(key)
|
75
78
|
@configuration.delete(key)
|
@@ -90,12 +93,11 @@ module Neo4j
|
|
90
93
|
# Retrieve the value of a config entry, returning the provided default if the key is not present
|
91
94
|
#
|
92
95
|
# ==== Parameters
|
93
|
-
# key
|
94
|
-
# default
|
95
|
-
# The default value to return if the parameter is not set.
|
96
|
+
# key:: The key to retrieve the parameter for.
|
97
|
+
# default::The default value to return if the parameter is not set.
|
96
98
|
#
|
97
99
|
# ==== Returns
|
98
|
-
#
|
100
|
+
# The value of the configuration parameter or the default.
|
99
101
|
#
|
100
102
|
def fetch(key, default)
|
101
103
|
@configuration.fetch(key, default)
|
@@ -116,7 +118,7 @@ module Neo4j
|
|
116
118
|
# Returns the configuration as a hash.
|
117
119
|
#
|
118
120
|
# ==== Returns
|
119
|
-
#
|
121
|
+
# The config as a hash.
|
120
122
|
#
|
121
123
|
def to_hash
|
122
124
|
@configuration
|
@@ -125,7 +127,7 @@ module Neo4j
|
|
125
127
|
# Returns the config as YAML.
|
126
128
|
#
|
127
129
|
# ==== Returns
|
128
|
-
#
|
130
|
+
# The config as YAML.
|
129
131
|
#
|
130
132
|
def to_yaml
|
131
133
|
require "yaml"
|
data/lib/neo4j/database.rb
CHANGED
data/lib/neo4j/equal.rb
CHANGED
data/lib/neo4j/event_handler.rb
CHANGED
@@ -1,6 +1,30 @@
|
|
1
1
|
module Neo4j
|
2
2
|
|
3
|
-
# Handles
|
3
|
+
# == Handles Transactional Events
|
4
|
+
#
|
5
|
+
# You can use this to receive event before the transaction commits.
|
6
|
+
# The following events are supported:
|
7
|
+
# * <tt>on_neo4j_started</tt>
|
8
|
+
# * <tt>on_neo4j_shutdown</tt>
|
9
|
+
# * <tt>on_node_created</tt>
|
10
|
+
# * <tt>on_node_deleted</tt>
|
11
|
+
# * <tt>on_relationship_created</tt>
|
12
|
+
# * <tt>on_relationship_deleted</tt>
|
13
|
+
# * <tt>on_property_changed</tt>
|
14
|
+
# * <tt>on_rel_property_changed</tt>
|
15
|
+
#
|
16
|
+
# === Usage
|
17
|
+
#
|
18
|
+
# class MyListener
|
19
|
+
# def on_node_deleted(node, old_props, tx_data)
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # to add an listener without starting neo4j:
|
24
|
+
# Neo4j.unstarted_db.event_handler.add(MyListener.new)
|
25
|
+
#
|
26
|
+
# You only need to implement the methods that you need.
|
27
|
+
#
|
4
28
|
class EventHandler
|
5
29
|
include org.neo4j.graphdb.event.TransactionEventHandler
|
6
30
|
|
@@ -88,18 +112,5 @@ module Neo4j
|
|
88
112
|
def rel_property_changed(rel, key, old_value, new_value)
|
89
113
|
@listeners.each {|li| li.on_rel_property_changed(rel, key, old_value, new_value) if li.respond_to?(:on_rel_property_changed)}
|
90
114
|
end
|
91
|
-
|
92
|
-
# TODO ?
|
93
|
-
def tx_finished(tx)
|
94
|
-
@listeners.each {|li| li.on_tx_finished(tx) if li.respond_to?(:on_tx_finished)}
|
95
|
-
end
|
96
|
-
|
97
|
-
def neo_started(neo_instance)
|
98
|
-
@listeners.each {|li| li.on_neo_started(neo_instance) if li.respond_to?(:on_neo_started)}
|
99
|
-
end
|
100
|
-
|
101
|
-
def neo_stopped(neo_instance)
|
102
|
-
@listeners.each {|li| li.on_neo_stopped(neo_instance) if li.respond_to?(:on_neo_stopped)}
|
103
|
-
end
|
104
115
|
end
|
105
116
|
end
|
@@ -34,11 +34,12 @@ module Neo4j
|
|
34
34
|
# class Phone
|
35
35
|
# include Neo4j::NodeMixin
|
36
36
|
# property :phone
|
37
|
-
#
|
37
|
+
# node_indexer Contact # put index on the Contact class instead
|
38
|
+
# index :phone
|
38
39
|
# end
|
39
40
|
#
|
40
41
|
# # Find an contact with a phone number, this works since they share the same index
|
41
|
-
# Contact.find('phone: 12345
|
42
|
+
# Contact.find('phone: 12345').first #=> a phone object !
|
42
43
|
#
|
43
44
|
# ==== Returns
|
44
45
|
# The indexer that should be used to index the given class
|
data/lib/neo4j/index/indexer.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Index
|
3
|
-
class Indexer
|
3
|
+
class Indexer
|
4
4
|
attr_reader :indexer_for, :field_types, :via_relationships
|
5
5
|
|
6
|
-
def initialize(clazz, type)
|
6
|
+
def initialize(clazz, type) #:nodoc:
|
7
7
|
# part of the unique name of the index
|
8
8
|
@indexer_for = clazz
|
9
9
|
|
@@ -19,7 +19,7 @@ module Neo4j
|
|
19
19
|
@parent_indexers = []
|
20
20
|
end
|
21
21
|
|
22
|
-
def inherit_fields_from(parent_index)
|
22
|
+
def inherit_fields_from(parent_index) #:nodoc:
|
23
23
|
return unless parent_index
|
24
24
|
@field_types.reverse_merge!(parent_index.field_types) if parent_index.respond_to?(:field_types)
|
25
25
|
@via_relationships.reverse_merge!(parent_index.via_relationships) if parent_index.respond_to?(:via_relationships)
|
@@ -30,7 +30,53 @@ module Neo4j
|
|
30
30
|
"Indexer @#{object_id} [index_for:#{@indexer_for}, field_types=#{@field_types.keys.join(', ')}, via=#{@via_relationships.inspect}]"
|
31
31
|
end
|
32
32
|
|
33
|
-
#
|
33
|
+
# Add an index on a field so that it will be automatically updated by neo4j transactional events.
|
34
|
+
#
|
35
|
+
# The index method takes an optional configuration hash which allows you to:
|
36
|
+
#
|
37
|
+
# === Add an index on an a property
|
38
|
+
#
|
39
|
+
# Example:
|
40
|
+
# class Person
|
41
|
+
# include Neo4j::NodeMixin
|
42
|
+
# index :name
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# When the property name is changed/deleted or the node created it will keep the lucene index in sync.
|
46
|
+
# You can then perform a lucene query like this: Person.find('name: andreas')
|
47
|
+
#'
|
48
|
+
# === Add index on other nodes.
|
49
|
+
#
|
50
|
+
# Example:
|
51
|
+
#
|
52
|
+
# class Person
|
53
|
+
# include Neo4j::NodeMixin
|
54
|
+
# has_n(:friends).to(Contact)
|
55
|
+
# has_n(:known_by).from(:friends)
|
56
|
+
# index :user_id, :via => :known_by
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# Notice that you *must* specify an incoming relationship with the via key, as shown above.
|
60
|
+
# In the example above an index <tt>user_id</tt> will be added to all Person nodes which has a <tt>friends</tt> relationship
|
61
|
+
# that person with that user_id. This allows you to do lucene queries on your friends properties.
|
62
|
+
#
|
63
|
+
# === Set the type value to index
|
64
|
+
# By default all values will be indexed as Strings.
|
65
|
+
# If you want for example to do a numerical range query you must tell Neo4j.rb to index it as a numeric value.
|
66
|
+
# You do that with the key <tt>type</tt>
|
67
|
+
#
|
68
|
+
# Example:
|
69
|
+
# class Person
|
70
|
+
# include Neo4j::NodeMixin
|
71
|
+
# index :weight, :type => Float
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# Supported values for <tt>:type</tt> is <tt>String</tt>, <tt>Float</tt> and <tt>Fixnum</tt>
|
75
|
+
#
|
76
|
+
# === For more information
|
77
|
+
# * See Neo4j::Index::LuceneQuery
|
78
|
+
# * See #find
|
79
|
+
#
|
34
80
|
def index(field, conf = {})
|
35
81
|
if conf[:via]
|
36
82
|
rel_dsl = @indexer_for._decl_rels[conf[:via]]
|
@@ -48,7 +94,7 @@ module Neo4j
|
|
48
94
|
end
|
49
95
|
end
|
50
96
|
|
51
|
-
def remove_index_on_fields(node, props, tx_data)
|
97
|
+
def remove_index_on_fields(node, props, tx_data) #:nodoc:
|
52
98
|
@field_types.keys.each { |field| rm_index(node, field, props[field]) if props[field] }
|
53
99
|
# remove all via indexed fields
|
54
100
|
@via_relationships.each_value do |dsl|
|
@@ -61,15 +107,15 @@ module Neo4j
|
|
61
107
|
end
|
62
108
|
end
|
63
109
|
|
64
|
-
def update_on_deleted_relationship(relationship)
|
110
|
+
def update_on_deleted_relationship(relationship) #:nodoc:
|
65
111
|
update_on_relationship(relationship, false)
|
66
112
|
end
|
67
113
|
|
68
|
-
def update_on_new_relationship(relationship)
|
114
|
+
def update_on_new_relationship(relationship) #:nodoc:
|
69
115
|
update_on_relationship(relationship, true)
|
70
116
|
end
|
71
117
|
|
72
|
-
def update_on_relationship(relationship, is_created)
|
118
|
+
def update_on_relationship(relationship, is_created) #:nodoc:
|
73
119
|
rel_type = relationship.rel_type
|
74
120
|
end_node = relationship._end_node
|
75
121
|
# find which via relationship match rel_type
|
@@ -93,7 +139,7 @@ module Neo4j
|
|
93
139
|
end
|
94
140
|
end
|
95
141
|
|
96
|
-
def update_index_on(node, field, old_val, new_val)
|
142
|
+
def update_index_on(node, field, old_val, new_val) #:nodoc:
|
97
143
|
if @via_relationships.include?(field)
|
98
144
|
dsl = @via_relationships[field]
|
99
145
|
to_class = dsl.to_class
|
@@ -106,42 +152,94 @@ module Neo4j
|
|
106
152
|
update_single_index_on(node, field, old_val, new_val)
|
107
153
|
end
|
108
154
|
|
109
|
-
def update_single_index_on(node, field, old_val, new_val)
|
155
|
+
def update_single_index_on(node, field, old_val, new_val) #:nodoc:
|
110
156
|
if @field_types.include?(field)
|
111
157
|
rm_index(node, field, old_val) if old_val
|
112
158
|
add_index(node, field, new_val) if new_val
|
113
159
|
end
|
114
160
|
end
|
115
161
|
|
162
|
+
# Returns true if there is an index on the given field.
|
163
|
+
#
|
116
164
|
def index?(field)
|
117
165
|
@field_types.include?(field.to_s)
|
118
166
|
end
|
119
167
|
|
120
|
-
|
168
|
+
# Returns the type of index for the given field (e.g. :exact or :fulltext)
|
169
|
+
#
|
170
|
+
def index_type_for(field) #:nodoc:
|
121
171
|
return nil unless index?(field)
|
122
172
|
@field_types[field.to_s]
|
123
173
|
end
|
124
174
|
|
175
|
+
# Returns true if there is an index of the given type defined.
|
125
176
|
def index_type?(type)
|
126
177
|
@field_types.values.include?(type)
|
127
178
|
end
|
128
179
|
|
180
|
+
# Adds an index on the given entity
|
181
|
+
# This is normally not needed since you can instead declare an index which will automatically keep
|
182
|
+
# the lucene index in sync. See #index
|
183
|
+
#
|
129
184
|
def add_index(entity, field, value)
|
130
185
|
return false unless @field_types.has_key?(field)
|
186
|
+
|
187
|
+
# we might need to know what type the properties are when indexing and querying
|
188
|
+
@decl_props ||= @indexer_for.respond_to?(:_decl_props) && @indexer_for._decl_props
|
189
|
+
|
190
|
+
type = @decl_props && @decl_props[field.to_sym] && @decl_props[field.to_sym][:type]
|
191
|
+
if type
|
192
|
+
raise "Can't index #{type} with value #{value} since it is not a #{type}" unless type === value
|
193
|
+
value = if String != type
|
194
|
+
org.neo4j.index.impl.lucene.ValueContext.new(value).indexNumeric
|
195
|
+
else
|
196
|
+
org.neo4j.index.impl.lucene.ValueContext.new(value)
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
131
201
|
index_for_field(field.to_s).add(entity, field, value)
|
132
202
|
@parent_indexers.each { |i| i.add_index(entity, field, value) }
|
133
203
|
end
|
134
204
|
|
205
|
+
# Removes an index on the given entity
|
206
|
+
# This is normally not needed since you can instead declare an index which will automatically keep
|
207
|
+
# the lucene index in sync. See #index
|
208
|
+
#
|
135
209
|
def rm_index(entity, field, value)
|
136
210
|
return false unless @field_types.has_key?(field)
|
137
211
|
index_for_field(field).remove(entity, field, value)
|
138
212
|
@parent_indexers.each { |i| i.rm_index(entity, field, value) }
|
139
213
|
end
|
140
214
|
|
215
|
+
# Performs a Lucene Query.
|
216
|
+
#
|
217
|
+
# In order to use this you have to declare an index on the fields first, see #index.
|
218
|
+
# Notice that you should close the lucene query after the query has been executed.
|
219
|
+
# You can do that either by provide an block or calling the Neo4j::Index::LuceneQuery#close
|
220
|
+
# method. When performing queries from Ruby on Rails you do not need this since it will be automatically closed
|
221
|
+
# (by Rack).
|
222
|
+
#
|
223
|
+
# === Example, with a block
|
224
|
+
#
|
225
|
+
# Person.find('name: kalle') {|query| puts "#{[*query].join(', )"}
|
226
|
+
#
|
227
|
+
# ==== Example
|
228
|
+
#
|
229
|
+
# query = Person.find('name: kalle')
|
230
|
+
# puts "First item #{query.first}"
|
231
|
+
# query.close
|
232
|
+
#
|
233
|
+
# === Return Value
|
234
|
+
# It will return a Neo4j::Index::LuceneQuery object
|
235
|
+
#
|
236
|
+
#
|
141
237
|
def find(query, params = {})
|
142
|
-
|
143
|
-
|
144
|
-
|
238
|
+
# we might need to know what type the properties are when indexing and querying
|
239
|
+
@decl_props ||= @indexer_for.respond_to?(:_decl_props) && @indexer_for._decl_props
|
240
|
+
|
241
|
+
index = index_for_type(params[:type] || :exact)
|
242
|
+
query = (params[:wrapped].nil? || params[:wrapped]) ? LuceneQuery.new(index, @decl_props, query) : index.query(query)
|
145
243
|
|
146
244
|
if block_given?
|
147
245
|
begin
|
@@ -155,7 +253,7 @@ module Neo4j
|
|
155
253
|
end
|
156
254
|
end
|
157
255
|
|
158
|
-
#
|
256
|
+
# delete the index, if no type is provided clear all types of indexes
|
159
257
|
def delete_index_type(type=nil)
|
160
258
|
if type
|
161
259
|
#raise "can't clear index of type '#{type}' since it does not exist ([#{@field_types.values.join(',')}] exists)" unless index_type?(type)
|
@@ -167,12 +265,14 @@ module Neo4j
|
|
167
265
|
end
|
168
266
|
end
|
169
267
|
|
170
|
-
def on_neo4j_shutdown
|
268
|
+
def on_neo4j_shutdown #:nodoc:
|
171
269
|
# Since we might start the database again we must make sure that we don't keep any references to
|
172
|
-
# an old lucene index
|
270
|
+
# an old lucene index in memory.
|
173
271
|
@indexes.clear
|
174
272
|
end
|
175
273
|
|
274
|
+
# Removes the cached lucene index, can be useful for some RSpecs which needs to restart the Neo4j.
|
275
|
+
#
|
176
276
|
def rm_field_type(type=nil)
|
177
277
|
if type
|
178
278
|
@field_types.delete_if { |k, v| v == type }
|
@@ -181,22 +281,22 @@ module Neo4j
|
|
181
281
|
end
|
182
282
|
end
|
183
283
|
|
184
|
-
def index_for_field(field)
|
284
|
+
def index_for_field(field) #:nodoc:
|
185
285
|
type = @field_types[field]
|
186
286
|
@indexes[type] ||= create_index_with(type)
|
187
287
|
end
|
188
288
|
|
189
|
-
def index_for_type(type)
|
289
|
+
def index_for_type(type) #:nodoc:
|
190
290
|
@indexes[type] ||= create_index_with(type)
|
191
291
|
end
|
192
292
|
|
193
|
-
def lucene_config(type)
|
293
|
+
def lucene_config(type) #:nodoc:
|
194
294
|
conf = Neo4j::Config[:lucene][type.to_sym]
|
195
295
|
raise "unknown lucene type #{type}" unless conf
|
196
296
|
conf
|
197
297
|
end
|
198
298
|
|
199
|
-
def create_index_with(type)
|
299
|
+
def create_index_with(type) #:nodoc:
|
200
300
|
db=Neo4j.started_db
|
201
301
|
index_config = lucene_config(type)
|
202
302
|
if @type == :node
|