neo4j 1.0.0.beta.20 → 3.0.0.alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG +243 -0
- data/CONTRIBUTORS +12 -0
- data/Gemfile +10 -11
- data/README.md +23 -0
- data/bin/neo4j-jars +33 -0
- data/config/locales/en.yml +5 -0
- data/config/neo4j/config.yml +98 -0
- data/lib/neo4j.rb +28 -68
- data/lib/neo4j/active_node.rb +60 -0
- data/lib/neo4j/active_node/callbacks.rb +41 -0
- data/lib/neo4j/active_node/has_n.rb +138 -0
- data/lib/neo4j/active_node/has_n/decl_rel.rb +236 -0
- data/lib/neo4j/active_node/has_n/nodes.rb +82 -0
- data/lib/neo4j/active_node/identity.rb +28 -0
- data/lib/neo4j/active_node/initialize.rb +24 -0
- data/lib/neo4j/active_node/labels.rb +142 -0
- data/lib/neo4j/active_node/persistence.rb +193 -0
- data/lib/neo4j/active_node/property.rb +41 -0
- data/lib/neo4j/active_node/rels.rb +11 -0
- data/lib/neo4j/active_node/validations.rb +51 -0
- data/lib/neo4j/railtie.rb +40 -0
- data/lib/neo4j/version.rb +1 -1
- data/lib/neo4j/wrapper.rb +25 -0
- data/neo4j.gemspec +25 -15
- metadata +136 -149
- data/README.rdoc +0 -135
- data/lib/generators/neo4j.rb +0 -65
- data/lib/generators/neo4j/model/model_generator.rb +0 -39
- data/lib/generators/neo4j/model/templates/model.erb +0 -7
- data/lib/neo4j/config.rb +0 -153
- data/lib/neo4j/database.rb +0 -56
- data/lib/neo4j/equal.rb +0 -21
- data/lib/neo4j/event_handler.rb +0 -116
- data/lib/neo4j/index/class_methods.rb +0 -62
- data/lib/neo4j/index/index.rb +0 -33
- data/lib/neo4j/index/indexer.rb +0 -312
- data/lib/neo4j/index/indexer_registry.rb +0 -68
- data/lib/neo4j/index/lucene_query.rb +0 -191
- data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
- data/lib/neo4j/jars/lucene-core-3.0.2.jar +0 -0
- data/lib/neo4j/jars/neo4j-index-1.2-1.2.M03.jar +0 -0
- data/lib/neo4j/jars/neo4j-kernel-1.2-1.2.M03.jar +0 -0
- data/lib/neo4j/jars/neo4j-lucene-index-0.2-1.2.M03.jar +0 -0
- data/lib/neo4j/load.rb +0 -21
- data/lib/neo4j/mapping/class_methods/init_node.rb +0 -50
- data/lib/neo4j/mapping/class_methods/init_rel.rb +0 -35
- data/lib/neo4j/mapping/class_methods/property.rb +0 -80
- data/lib/neo4j/mapping/class_methods/relationship.rb +0 -90
- data/lib/neo4j/mapping/class_methods/root.rb +0 -31
- data/lib/neo4j/mapping/class_methods/rule.rb +0 -295
- data/lib/neo4j/mapping/decl_relationship_dsl.rb +0 -214
- data/lib/neo4j/mapping/has_n.rb +0 -83
- data/lib/neo4j/mapping/node_mixin.rb +0 -97
- data/lib/neo4j/mapping/relationship_mixin.rb +0 -117
- data/lib/neo4j/model.rb +0 -4
- data/lib/neo4j/neo4j.rb +0 -95
- data/lib/neo4j/node.rb +0 -131
- data/lib/neo4j/node_mixin.rb +0 -4
- data/lib/neo4j/node_relationship.rb +0 -149
- data/lib/neo4j/node_traverser.rb +0 -157
- data/lib/neo4j/property.rb +0 -111
- data/lib/neo4j/rails/finders.rb +0 -121
- data/lib/neo4j/rails/lucene_connection_closer.rb +0 -19
- data/lib/neo4j/rails/mapping/property.rb +0 -35
- data/lib/neo4j/rails/model.rb +0 -324
- data/lib/neo4j/rails/railtie.rb +0 -16
- data/lib/neo4j/rails/transaction.rb +0 -67
- data/lib/neo4j/rails/tx_methods.rb +0 -15
- data/lib/neo4j/rails/validations/non_nil.rb +0 -11
- data/lib/neo4j/rails/validations/uniqueness.rb +0 -31
- data/lib/neo4j/rails/value.rb +0 -124
- data/lib/neo4j/rails/value_properties.rb +0 -29
- data/lib/neo4j/relationship.rb +0 -169
- data/lib/neo4j/relationship_mixin.rb +0 -4
- data/lib/neo4j/relationship_traverser.rb +0 -92
- data/lib/neo4j/to_java.rb +0 -31
- data/lib/neo4j/transaction.rb +0 -68
- data/lib/neo4j/type_converters.rb +0 -98
data/lib/neo4j/equal.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
|
3
|
-
# == This mixin is used for both nodes and relationships to decide if two entities are equal or not.
|
4
|
-
#
|
5
|
-
module Equal
|
6
|
-
def equal?(o)
|
7
|
-
eql?(o)
|
8
|
-
end
|
9
|
-
|
10
|
-
def eql?(o)
|
11
|
-
return false unless o.respond_to?(:getId)
|
12
|
-
o.getId == getId
|
13
|
-
end
|
14
|
-
|
15
|
-
def ==(o)
|
16
|
-
eql?(o)
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
data/lib/neo4j/event_handler.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
|
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
|
-
#
|
28
|
-
class EventHandler
|
29
|
-
include org.neo4j.graphdb.event.TransactionEventHandler
|
30
|
-
|
31
|
-
def initialize
|
32
|
-
@listeners = []
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
def after_commit(data, state)
|
37
|
-
end
|
38
|
-
|
39
|
-
def after_rollback(data, state)
|
40
|
-
end
|
41
|
-
|
42
|
-
def before_commit(data)
|
43
|
-
data.created_nodes.each{|node| node_created(node)}
|
44
|
-
data.assigned_node_properties.each { |tx_data| property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, tx_data.value) }
|
45
|
-
data.removed_node_properties.each { |tx_data| property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, nil) unless data.deleted_nodes.include?(tx_data.entity) }
|
46
|
-
data.deleted_nodes.each { |node| node_deleted(node, deleted_properties_for(node,data), data)}
|
47
|
-
data.created_relationships.each {|rel| relationship_created(rel, data)}
|
48
|
-
data.deleted_relationships.each {|rel| relationship_deleted(rel, deleted_rel_properties_for(rel, data), data)}
|
49
|
-
data.assigned_relationship_properties.each { |tx_data| rel_property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, tx_data.value) }
|
50
|
-
data.removed_relationship_properties.each {|tx_data| rel_property_changed(tx_data.entity, tx_data.key, tx_data.previously_commited_value, nil) unless data.deleted_relationships.include?(tx_data.entity) }
|
51
|
-
end
|
52
|
-
|
53
|
-
def deleted_properties_for(node, data)
|
54
|
-
data.removed_node_properties.find_all{|tx_data| tx_data.entity == node}.inject({}) do |memo, tx_data|
|
55
|
-
memo[tx_data.key] = tx_data.previously_commited_value
|
56
|
-
memo
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def deleted_rel_properties_for(rel, data)
|
61
|
-
data.removed_relationship_properties.find_all{|tx_data| tx_data.entity == rel}.inject({}) do |memo, tx_data|
|
62
|
-
memo[tx_data.key] = tx_data.previously_commited_value
|
63
|
-
memo
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def add(listener)
|
68
|
-
@listeners << listener unless @listeners.include?(listener)
|
69
|
-
end
|
70
|
-
|
71
|
-
def remove(listener)
|
72
|
-
@listeners.delete(listener)
|
73
|
-
end
|
74
|
-
|
75
|
-
def remove_all
|
76
|
-
@listeners = []
|
77
|
-
end
|
78
|
-
|
79
|
-
def print
|
80
|
-
puts "Listeners #{@listeners.size}"
|
81
|
-
@listeners.each {|li| puts " Listener '#{li}'"}
|
82
|
-
end
|
83
|
-
|
84
|
-
def neo4j_started(db)
|
85
|
-
@listeners.each { |li| li.on_neo4j_started(db) if li.respond_to?(:on_neo4j_started) }
|
86
|
-
end
|
87
|
-
|
88
|
-
def neo4j_shutdown(db)
|
89
|
-
@listeners.each { |li| li.on_neo4j_shutdown(db) if li.respond_to?(:on_neo4j_shutdown) }
|
90
|
-
end
|
91
|
-
|
92
|
-
def node_created(node)
|
93
|
-
@listeners.each {|li| li.on_node_created(node) if li.respond_to?(:on_node_created)}
|
94
|
-
end
|
95
|
-
|
96
|
-
def node_deleted(node,old_properties, data)
|
97
|
-
@listeners.each {|li| li.on_node_deleted(node,old_properties, data) if li.respond_to?(:on_node_deleted)}
|
98
|
-
end
|
99
|
-
|
100
|
-
def relationship_created(relationship, tx_data)
|
101
|
-
@listeners.each {|li| li.on_relationship_created(relationship, tx_data) if li.respond_to?(:on_relationship_created)}
|
102
|
-
end
|
103
|
-
|
104
|
-
def relationship_deleted(relationship, old_props, data)
|
105
|
-
@listeners.each {|li| li.on_relationship_deleted(relationship, old_props, data) if li.respond_to?(:on_relationship_deleted)}
|
106
|
-
end
|
107
|
-
|
108
|
-
def property_changed(node, key, old_value, new_value)
|
109
|
-
@listeners.each {|li| li.on_property_changed(node, key, old_value, new_value) if li.respond_to?(:on_property_changed)}
|
110
|
-
end
|
111
|
-
|
112
|
-
def rel_property_changed(rel, key, old_value, new_value)
|
113
|
-
@listeners.each {|li| li.on_rel_property_changed(rel, key, old_value, new_value) if li.respond_to?(:on_rel_property_changed)}
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module Index
|
3
|
-
module ClassMethods
|
4
|
-
attr_reader :_indexer
|
5
|
-
|
6
|
-
extend Forwardable
|
7
|
-
|
8
|
-
##
|
9
|
-
# See Neo4j::Index::Indexer#index
|
10
|
-
# Forwards to the indexer that should be used.
|
11
|
-
# It is possible to share the same index for several different classes, see #node_indexer.
|
12
|
-
# :singleton-method: index
|
13
|
-
|
14
|
-
##
|
15
|
-
# See Neo4j::Index::Indexer#find
|
16
|
-
# Forwards to the indexer that should be used.
|
17
|
-
# It is possible to share the same index for several different classes, see #node_indexer.
|
18
|
-
# :singleton-method: find
|
19
|
-
|
20
|
-
|
21
|
-
def_delegators :@_indexer, :index, :find, :index?, :index_type?, :delete_index_type, :rm_field_type, :add_index, :rm_index, :index_type_for, :index_name
|
22
|
-
|
23
|
-
|
24
|
-
# Sets which indexer should be used for the given node class.
|
25
|
-
# You can share an indexer between several different classes.
|
26
|
-
#
|
27
|
-
# ==== Example
|
28
|
-
# class Contact
|
29
|
-
# include Neo4j::NodeMixin
|
30
|
-
# index :name
|
31
|
-
# has_one :phone
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# class Phone
|
35
|
-
# include Neo4j::NodeMixin
|
36
|
-
# property :phone
|
37
|
-
# node_indexer Contact # put index on the Contact class instead
|
38
|
-
# index :phone
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# # Find an contact with a phone number, this works since they share the same index
|
42
|
-
# Contact.find('phone: 12345').first #=> a phone object !
|
43
|
-
#
|
44
|
-
# ==== Returns
|
45
|
-
# The indexer that should be used to index the given class
|
46
|
-
def node_indexer(clazz)
|
47
|
-
indexer(clazz, :node)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Sets which indexer should be used for the given relationship class
|
51
|
-
# Same as #node_indexer except that it indexes relationships instead of nodes.
|
52
|
-
#
|
53
|
-
def rel_indexer(clazz)
|
54
|
-
indexer(clazz, :rel)
|
55
|
-
end
|
56
|
-
|
57
|
-
def indexer(clazz, type) #:nodoc:
|
58
|
-
@_indexer = IndexerRegistry.create_for(self, clazz, type)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
data/lib/neo4j/index/index.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
|
3
|
-
module Index
|
4
|
-
|
5
|
-
# Adds an index on the given property
|
6
|
-
# Notice that you normally don't have to do that since you simply can declare
|
7
|
-
# that the property and index should be updated automatically by using the class method #index.
|
8
|
-
#
|
9
|
-
# The index operation will take place immediately unlike when using the Neo4j::Index::ClassMethods::index
|
10
|
-
# method which instead will guarantee that the neo4j database and the lucene database will be consistent.
|
11
|
-
# It uses a two phase commit when the transaction is about to be committed.
|
12
|
-
#
|
13
|
-
# ==== See also
|
14
|
-
# Neo4j::Index::ClassMethods::index
|
15
|
-
#
|
16
|
-
def add_index(field, value=self[field])
|
17
|
-
self.class.add_index(wrapped_entity, field.to_s, value)
|
18
|
-
end
|
19
|
-
|
20
|
-
# Removes an index on the given property.
|
21
|
-
# Just like #add_index this is normally not needed since you instead can declare it with the
|
22
|
-
# #index class method instead.
|
23
|
-
#
|
24
|
-
# ==== See also
|
25
|
-
# Neo4j::Index::ClassMethods::index
|
26
|
-
# Neo4j::Index#add_index
|
27
|
-
#
|
28
|
-
def rm_index(field, value=self[field])
|
29
|
-
self.class.rm_index(wrapped_entity, field.to_s, value)
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
data/lib/neo4j/index/indexer.rb
DELETED
@@ -1,312 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module Index
|
3
|
-
class Indexer
|
4
|
-
attr_reader :indexer_for, :field_types, :via_relationships
|
5
|
-
|
6
|
-
def initialize(clazz, type) #:nodoc:
|
7
|
-
# part of the unique name of the index
|
8
|
-
@indexer_for = clazz
|
9
|
-
|
10
|
-
# do we want to index nodes or relationships ?
|
11
|
-
@type = type
|
12
|
-
|
13
|
-
@indexes = {} # key = type, value = java neo4j index
|
14
|
-
@field_types = {} # key = field, value = type (e.g. :exact or :fulltext)
|
15
|
-
@via_relationships = {} # key = field, value = relationship
|
16
|
-
|
17
|
-
# to enable subclass indexing to work properly, store a list of parent indexers and
|
18
|
-
# whenever an operation is performed on this one, perform it on all
|
19
|
-
@parent_indexers = []
|
20
|
-
end
|
21
|
-
|
22
|
-
def inherit_fields_from(parent_index) #:nodoc:
|
23
|
-
return unless parent_index
|
24
|
-
@field_types.reverse_merge!(parent_index.field_types) if parent_index.respond_to?(:field_types)
|
25
|
-
@via_relationships.reverse_merge!(parent_index.via_relationships) if parent_index.respond_to?(:via_relationships)
|
26
|
-
@parent_indexers << parent_index
|
27
|
-
end
|
28
|
-
|
29
|
-
def to_s
|
30
|
-
"Indexer @#{object_id} [index_for:#{@indexer_for}, field_types=#{@field_types.keys.join(', ')}, via=#{@via_relationships.inspect}]"
|
31
|
-
end
|
32
|
-
|
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> on the property.
|
67
|
-
#
|
68
|
-
# Example:
|
69
|
-
# class Person
|
70
|
-
# include Neo4j::NodeMixin
|
71
|
-
# property :weight, :type => Float
|
72
|
-
# index :weight
|
73
|
-
# end
|
74
|
-
#
|
75
|
-
# Supported values for <tt>:type</tt> is <tt>String</tt>, <tt>Float</tt>, <tt>Date</tt>, <tt>DateTime</tt> and <tt>Fixnum</tt>
|
76
|
-
#
|
77
|
-
# === For more information
|
78
|
-
# * See Neo4j::Index::LuceneQuery
|
79
|
-
# * See #find
|
80
|
-
#
|
81
|
-
def index(field, conf = {})
|
82
|
-
if conf[:via]
|
83
|
-
rel_dsl = @indexer_for._decl_rels[conf[:via]]
|
84
|
-
raise "No relationship defined for '#{conf[:via]}'. Check class '#{@indexer_for}': index :#{field}, via=>:#{conf[:via]} <-- error. Define it with a has_one or has_n" unless rel_dsl
|
85
|
-
raise "Only incoming relationship are possible to define index on. Check class '#{@indexer_for}': index :#{field}, via=>:#{conf[:via]}" unless rel_dsl.incoming?
|
86
|
-
via_indexer = rel_dsl.target_class._indexer
|
87
|
-
|
88
|
-
field = field.to_s
|
89
|
-
@via_relationships[field] = rel_dsl
|
90
|
-
conf.delete :via # avoid endless recursion
|
91
|
-
via_indexer.index(field, conf)
|
92
|
-
else
|
93
|
-
# raise "Already defined an (via?) index on #{field}, Using the same index for from two classes ? Check index :#{field}, :via => :#{@indexer_for}" if @field_types[field.to_s]
|
94
|
-
@field_types[field.to_s] = conf[:type] || :exact
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def remove_index_on_fields(node, props, tx_data) #:nodoc:
|
99
|
-
@field_types.keys.each { |field| rm_index(node, field, props[field]) if props[field] }
|
100
|
-
# remove all via indexed fields
|
101
|
-
@via_relationships.each_value do |dsl|
|
102
|
-
indexer = dsl.target_class._indexer
|
103
|
-
tx_data.deleted_relationships.each do |rel|
|
104
|
-
start_node = rel._start_node
|
105
|
-
next if node != rel._end_node
|
106
|
-
indexer.remove_index_on_fields(start_node, props, tx_data)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def update_on_deleted_relationship(relationship) #:nodoc:
|
112
|
-
update_on_relationship(relationship, false)
|
113
|
-
end
|
114
|
-
|
115
|
-
def update_on_new_relationship(relationship) #:nodoc:
|
116
|
-
update_on_relationship(relationship, true)
|
117
|
-
end
|
118
|
-
|
119
|
-
def update_on_relationship(relationship, is_created) #:nodoc:
|
120
|
-
rel_type = relationship.rel_type
|
121
|
-
end_node = relationship._end_node
|
122
|
-
# find which via relationship match rel_type
|
123
|
-
@via_relationships.each_pair do |field, dsl|
|
124
|
-
# have we declared an index on this changed relationship ?
|
125
|
-
next unless dsl.rel_type == rel_type
|
126
|
-
|
127
|
-
# yes, so find the node and value we should update the index on
|
128
|
-
val = end_node[field]
|
129
|
-
start_node = relationship._start_node
|
130
|
-
|
131
|
-
# find the indexer to use
|
132
|
-
indexer = dsl.target_class._indexer
|
133
|
-
|
134
|
-
# is the relationship created or deleted ?
|
135
|
-
if is_created
|
136
|
-
indexer.update_index_on(start_node, field, nil, val)
|
137
|
-
else
|
138
|
-
indexer.update_index_on(start_node, field, val, nil)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def update_index_on(node, field, old_val, new_val) #:nodoc:
|
144
|
-
if @via_relationships.include?(field)
|
145
|
-
dsl = @via_relationships[field]
|
146
|
-
target_class = dsl.target_class
|
147
|
-
|
148
|
-
dsl._all_relationships(node).each do |rel|
|
149
|
-
other = rel._start_node
|
150
|
-
target_class._indexer.update_single_index_on(other, field, old_val, new_val)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
update_single_index_on(node, field, old_val, new_val)
|
154
|
-
end
|
155
|
-
|
156
|
-
def update_single_index_on(node, field, old_val, new_val) #:nodoc:
|
157
|
-
if @field_types.include?(field)
|
158
|
-
rm_index(node, field, old_val) if old_val
|
159
|
-
add_index(node, field, new_val) if new_val
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
# Returns true if there is an index on the given field.
|
164
|
-
#
|
165
|
-
def index?(field)
|
166
|
-
@field_types.include?(field.to_s)
|
167
|
-
end
|
168
|
-
|
169
|
-
# Returns the type of index for the given field (e.g. :exact or :fulltext)
|
170
|
-
#
|
171
|
-
def index_type_for(field) #:nodoc:
|
172
|
-
return nil unless index?(field)
|
173
|
-
@field_types[field.to_s]
|
174
|
-
end
|
175
|
-
|
176
|
-
# Returns true if there is an index of the given type defined.
|
177
|
-
def index_type?(type)
|
178
|
-
@field_types.values.include?(type)
|
179
|
-
end
|
180
|
-
|
181
|
-
# Adds an index on the given entity
|
182
|
-
# This is normally not needed since you can instead declare an index which will automatically keep
|
183
|
-
# the lucene index in sync. See #index
|
184
|
-
#
|
185
|
-
def add_index(entity, field, value)
|
186
|
-
return false unless @field_types.has_key?(field)
|
187
|
-
|
188
|
-
# we might need to know what type the properties are when indexing and querying
|
189
|
-
@decl_props ||= @indexer_for.respond_to?(:_decl_props) && @indexer_for._decl_props
|
190
|
-
|
191
|
-
type = @decl_props && @decl_props[field.to_sym] && @decl_props[field.to_sym][:type]
|
192
|
-
if type
|
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
|
-
end
|
199
|
-
|
200
|
-
index_for_field(field.to_s).add(entity, field, value)
|
201
|
-
@parent_indexers.each { |i| i.add_index(entity, field, value) }
|
202
|
-
end
|
203
|
-
|
204
|
-
# Removes an index on the given entity
|
205
|
-
# This is normally not needed since you can instead declare an index which will automatically keep
|
206
|
-
# the lucene index in sync. See #index
|
207
|
-
#
|
208
|
-
def rm_index(entity, field, value)
|
209
|
-
return false unless @field_types.has_key?(field)
|
210
|
-
index_for_field(field).remove(entity, field, value)
|
211
|
-
@parent_indexers.each { |i| i.rm_index(entity, field, value) }
|
212
|
-
end
|
213
|
-
|
214
|
-
# Performs a Lucene Query.
|
215
|
-
#
|
216
|
-
# In order to use this you have to declare an index on the fields first, see #index.
|
217
|
-
# Notice that you should close the lucene query after the query has been executed.
|
218
|
-
# You can do that either by provide an block or calling the Neo4j::Index::LuceneQuery#close
|
219
|
-
# method. When performing queries from Ruby on Rails you do not need this since it will be automatically closed
|
220
|
-
# (by Rack).
|
221
|
-
#
|
222
|
-
# === Example, with a block
|
223
|
-
#
|
224
|
-
# Person.find('name: kalle') {|query| puts "#{[*query].join(', )"}
|
225
|
-
#
|
226
|
-
# ==== Example
|
227
|
-
#
|
228
|
-
# query = Person.find('name: kalle')
|
229
|
-
# puts "First item #{query.first}"
|
230
|
-
# query.close
|
231
|
-
#
|
232
|
-
# === Return Value
|
233
|
-
# It will return a Neo4j::Index::LuceneQuery object
|
234
|
-
#
|
235
|
-
#
|
236
|
-
def find(query, params = {})
|
237
|
-
# we might need to know what type the properties are when indexing and querying
|
238
|
-
@decl_props ||= @indexer_for.respond_to?(:_decl_props) && @indexer_for._decl_props
|
239
|
-
|
240
|
-
index = index_for_type(params[:type] || :exact)
|
241
|
-
query = (params[:wrapped].nil? || params[:wrapped]) ? LuceneQuery.new(index, @decl_props, query) : index.query(query)
|
242
|
-
|
243
|
-
if block_given?
|
244
|
-
begin
|
245
|
-
ret = yield query
|
246
|
-
ensure
|
247
|
-
query.close
|
248
|
-
end
|
249
|
-
ret
|
250
|
-
else
|
251
|
-
query
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
# delete the index, if no type is provided clear all types of indexes
|
256
|
-
def delete_index_type(type=nil)
|
257
|
-
if type
|
258
|
-
#raise "can't clear index of type '#{type}' since it does not exist ([#{@field_types.values.join(',')}] exists)" unless index_type?(type)
|
259
|
-
@indexes[type] && @indexes[type].delete
|
260
|
-
@indexes[type] = nil
|
261
|
-
else
|
262
|
-
@indexes.each_value { |index| index.delete }
|
263
|
-
@indexes.clear
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
def on_neo4j_shutdown #:nodoc:
|
268
|
-
# Since we might start the database again we must make sure that we don't keep any references to
|
269
|
-
# an old lucene index in memory.
|
270
|
-
@indexes.clear
|
271
|
-
end
|
272
|
-
|
273
|
-
# Removes the cached lucene index, can be useful for some RSpecs which needs to restart the Neo4j.
|
274
|
-
#
|
275
|
-
def rm_field_type(type=nil)
|
276
|
-
if type
|
277
|
-
@field_types.delete_if { |k, v| v == type }
|
278
|
-
else
|
279
|
-
@field_types.clear
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
def index_for_field(field) #:nodoc:
|
284
|
-
type = @field_types[field]
|
285
|
-
@indexes[type] ||= create_index_with(type)
|
286
|
-
end
|
287
|
-
|
288
|
-
def index_for_type(type) #:nodoc:
|
289
|
-
@indexes[type] ||= create_index_with(type)
|
290
|
-
end
|
291
|
-
|
292
|
-
def lucene_config(type) #:nodoc:
|
293
|
-
conf = Neo4j::Config[:lucene][type.to_sym]
|
294
|
-
raise "unknown lucene type #{type}" unless conf
|
295
|
-
conf
|
296
|
-
end
|
297
|
-
|
298
|
-
def create_index_with(type) #:nodoc:
|
299
|
-
db=Neo4j.started_db
|
300
|
-
index_config = lucene_config(type)
|
301
|
-
if @type == :node
|
302
|
-
db.lucene.for_nodes("#{@indexer_for}-#{type}", index_config)
|
303
|
-
else
|
304
|
-
db.lucene.for_relationships("#{@indexer_for}-#{type}", index_config)
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
end
|
309
|
-
|
310
|
-
end
|
311
|
-
|
312
|
-
end
|