neo4j-core 0.0.9-java → 0.0.10-java
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/neo4j-core.rb +1 -1
- data/lib/neo4j-core/cypher/cypher.rb +19 -0
- data/lib/neo4j-core/index/class_methods.rb +12 -12
- data/lib/neo4j-core/index/index.rb +3 -3
- data/lib/neo4j-core/relationship/relationship.rb +1 -1
- data/lib/neo4j-core/rels/traverser.rb +12 -10
- data/lib/neo4j-core/traversal/traverser.rb +122 -21
- data/lib/neo4j-core/version.rb +1 -1
- data/lib/neo4j-core/wrapper/wrapper.rb +7 -0
- data/lib/neo4j/node.rb +23 -0
- data/lib/neo4j/relationship.rb +14 -0
- metadata +2 -2
data/lib/neo4j-core.rb
CHANGED
@@ -170,6 +170,24 @@ module Neo4j
|
|
170
170
|
MatchNode.new(self, other, expressions, :outgoing)
|
171
171
|
end
|
172
172
|
|
173
|
+
def outgoing(rel_type)
|
174
|
+
node = NodeVar.new(@expressions, @variables)
|
175
|
+
MatchRelLeft.new(self, ":`#{rel_type}`", expressions, :outgoing) > node
|
176
|
+
node
|
177
|
+
end
|
178
|
+
|
179
|
+
def incoming(rel_type)
|
180
|
+
node = NodeVar.new(@expressions, @variables)
|
181
|
+
MatchRelLeft.new(self, ":`#{rel_type}`", expressions, :incoming) < node
|
182
|
+
node
|
183
|
+
end
|
184
|
+
|
185
|
+
def both(rel_type)
|
186
|
+
node = NodeVar.new(@expressions, @variables)
|
187
|
+
MatchRelLeft.new(self, ":`#{rel_type}`", expressions, :both) < node
|
188
|
+
node
|
189
|
+
end
|
190
|
+
|
173
191
|
# Incoming relationship to other node
|
174
192
|
# @param [Symbol, #var_name] other either a node (Symbol, #var_name)
|
175
193
|
# @return [MatchRelLeft, MatchNode]
|
@@ -665,6 +683,7 @@ module Neo4j
|
|
665
683
|
def initialize(expressions, variables)
|
666
684
|
@var_name = "v#{variables.size}"
|
667
685
|
variables << self
|
686
|
+
@variables = variables
|
668
687
|
@expressions = expressions
|
669
688
|
end
|
670
689
|
|
@@ -21,18 +21,7 @@ module Neo4j
|
|
21
21
|
# trigger_on :ntype => 'foo', :name => ['bar', 'foobar']
|
22
22
|
#
|
23
23
|
# prefix_index_name do
|
24
|
-
#
|
25
|
-
# return "" unless @indexer_for.respond_to?(:ref_node_for_class)
|
26
|
-
# ref_node = @indexer_for.ref_node_for_class.wrapper
|
27
|
-
# prefix = ref_node.send(:_index_prefix) if ref_node.respond_to?(:_index_prefix)
|
28
|
-
# prefix ||= ref_node[:name] # To maintain backward compatiblity
|
29
|
-
# prefix.blank? ? "" : prefix + "_"
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
#
|
33
|
-
# numeric do
|
34
|
-
# type = decl_props && decl_props[field.to_sym] && decl_props[field.to_sym][:type]
|
35
|
-
# type && !type.is_a?(String)
|
24
|
+
# "Foo" # this is used for example in multitenancy to let each domain have there own index files
|
36
25
|
# end
|
37
26
|
# end
|
38
27
|
# end
|
@@ -64,6 +53,17 @@ module Neo4j
|
|
64
53
|
@_indexer ||= IndexerRegistry.instance.register(Indexer.new(index_config))
|
65
54
|
end
|
66
55
|
|
56
|
+
# You can specify which nodes should be triggered.
|
57
|
+
# The index can be triggered by one or more properties having one or more values.
|
58
|
+
# This can also be done using the #node_indexer or #rel_indexer methods.
|
59
|
+
#
|
60
|
+
# @example trigger on property :type being 'MyType1'
|
61
|
+
# Neo4j::NodeIndex.trigger_on(:type => 'MyType1')
|
62
|
+
#
|
63
|
+
def trigger_on(hash)
|
64
|
+
_config.trigger_on(hash)
|
65
|
+
end
|
66
|
+
|
67
67
|
|
68
68
|
class << self
|
69
69
|
private
|
@@ -2,7 +2,7 @@ module Neo4j
|
|
2
2
|
module Core
|
3
3
|
|
4
4
|
# A mixin which adds indexing behaviour to your own Ruby class
|
5
|
-
# You are expected to implement the method `
|
5
|
+
# You are expected to implement the method `java_entity` returning the underlying Neo4j Node or Relationship.
|
6
6
|
module Index
|
7
7
|
|
8
8
|
# Adds an index on the given property
|
@@ -16,7 +16,7 @@ module Neo4j
|
|
16
16
|
# @see Neo4j::Core::Index::ClassMethods#add_index
|
17
17
|
#
|
18
18
|
def add_index(field, value=self[field])
|
19
|
-
self.class.add_index(
|
19
|
+
self.class.add_index(java_entity, field.to_s, value)
|
20
20
|
end
|
21
21
|
|
22
22
|
# Removes an index on the given property.
|
@@ -26,7 +26,7 @@ module Neo4j
|
|
26
26
|
# @see Neo4j::Core::Index::ClassMethods#rm_index
|
27
27
|
#
|
28
28
|
def rm_index(field, value=self[field])
|
29
|
-
self.class.rm_index(
|
29
|
+
self.class.rm_index(java_entity, field.to_s, value)
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
@@ -29,7 +29,7 @@ module Neo4j
|
|
29
29
|
iter = iterator
|
30
30
|
while (iter.has_next())
|
31
31
|
rel = iter.next
|
32
|
-
yield rel.wrapper if
|
32
|
+
yield rel.wrapper if match_between?(rel)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -44,27 +44,29 @@ module Neo4j
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# @return [true,false] true if it match the specified other node
|
47
|
-
# @see #
|
48
|
-
def
|
49
|
-
if @
|
47
|
+
# @see #between
|
48
|
+
def match_between?(rel)
|
49
|
+
if @between.nil?
|
50
50
|
true
|
51
51
|
elsif @dir == :outgoing
|
52
|
-
rel._end_node == @
|
52
|
+
rel._end_node == @between
|
53
53
|
elsif @dir == :incoming
|
54
|
-
rel._start_node == @
|
54
|
+
rel._start_node == @between
|
55
55
|
else
|
56
|
-
rel._start_node == @
|
56
|
+
rel._start_node == @between || rel._end_node == @between
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
60
|
# Specifies that we only want relationship to the given node
|
61
|
-
# @param [Neo4j::Node]
|
61
|
+
# @param [Neo4j::Node] between a node or an object that implements the Neo4j::Core::Equal mixin
|
62
62
|
# @return self
|
63
|
-
def
|
64
|
-
@
|
63
|
+
def between(between)
|
64
|
+
@between = between
|
65
65
|
self
|
66
66
|
end
|
67
67
|
|
68
|
+
alias_method :to_other, :between
|
69
|
+
|
68
70
|
# Deletes all the relationships
|
69
71
|
def del
|
70
72
|
each { |rel| rel.del }
|
@@ -2,6 +2,54 @@ module Neo4j
|
|
2
2
|
module Core
|
3
3
|
module Traversal
|
4
4
|
|
5
|
+
class CypherQuery
|
6
|
+
include Enumerable
|
7
|
+
attr_accessor :query, :return_variable
|
8
|
+
|
9
|
+
def initialize(start_id, dir, types, query_hash=nil, &block)
|
10
|
+
this = self
|
11
|
+
|
12
|
+
rel_type = ":#{types.map{|x| "`#{x}`"}.join('|')}"
|
13
|
+
|
14
|
+
@query = Neo4j::Cypher.new do
|
15
|
+
default_ret = node(:default_ret)
|
16
|
+
n = node(start_id)
|
17
|
+
case dir
|
18
|
+
when :outgoing then
|
19
|
+
n > rel_type > default_ret
|
20
|
+
when :incoming then
|
21
|
+
n < rel_type < default_ret
|
22
|
+
when :both then
|
23
|
+
n - rel_type - default_ret
|
24
|
+
end
|
25
|
+
|
26
|
+
# where statement
|
27
|
+
ret_maybe = block && self.instance_exec(default_ret, &block)
|
28
|
+
ret = ret_maybe.respond_to?(:var_name) ? ret_maybe : default_ret
|
29
|
+
if query_hash
|
30
|
+
expr = []
|
31
|
+
query_hash.each{|pair| expr << (ret[pair[0]] == pair[1])}.to_a
|
32
|
+
expr.each_with_index do |obj, i|
|
33
|
+
Neo4j::Core::Cypher::ExprOp.new(obj, expr[i+1], "and") if i < expr.size - 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
this.return_variable = ret.var_name.to_sym
|
38
|
+
ret
|
39
|
+
end.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
@query
|
44
|
+
end
|
45
|
+
|
46
|
+
def each
|
47
|
+
Neo4j._query(query).each do |r|
|
48
|
+
yield r[return_variable]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
5
53
|
# By using this class you can both specify traversals and create new relationships.
|
6
54
|
# This object is return from the Neo4j::Core::Traversal methods.
|
7
55
|
# @see Neo4j::Core::Traversal#outgoing
|
@@ -17,14 +65,27 @@ module Neo4j
|
|
17
65
|
if type.nil?
|
18
66
|
raise "Traversing all relationship in direction #{dir.inspect} not supported, only :both supported" unless dir == :both
|
19
67
|
@td = Java::OrgNeo4jKernelImplTraversal::TraversalDescriptionImpl.new.breadth_first()
|
68
|
+
elsif (dir == :both)
|
69
|
+
both(type)
|
70
|
+
elsif (dir == :incoming)
|
71
|
+
incoming(type)
|
72
|
+
elsif (dir == :outgoing)
|
73
|
+
outgoing(type)
|
20
74
|
else
|
21
|
-
|
22
|
-
@dir = dir_to_java(dir)
|
23
|
-
@td = Java::OrgNeo4jKernelImplTraversal::TraversalDescriptionImpl.new.breadth_first().relationships(@type, @dir)
|
75
|
+
raise "Illegal direction #{dir.inspect}, expected :outgoing, :incoming or :both"
|
24
76
|
end
|
25
77
|
end
|
26
78
|
|
27
79
|
|
80
|
+
def query(query_hash = nil, &block)
|
81
|
+
# only one direction is supported
|
82
|
+
rel_types = [@outgoing_rel_types, @incoming_rel_types, @both_rel_types].find_all { |x| !x.nil? }
|
83
|
+
raise "Only one direction is allowed, outgoing:#{@outgoing_rel_types}, incoming:#{@incoming_rel_types}, @both:#{@both_rel_types}" if rel_types.count != 1
|
84
|
+
start_id = @from.neo_id
|
85
|
+
dir = (@outgoing_rel_types && :outgoing) || (@incoming_rel_types && :incoming) || (@both_rel_types && :both)
|
86
|
+
CypherQuery.new(start_id, dir, rel_types.first, query_hash, &block)
|
87
|
+
end
|
88
|
+
|
28
89
|
# Sets traversing depth first.
|
29
90
|
#
|
30
91
|
# The <tt>pre_or_post</tt> parameter parameter can have two values: :pre or :post
|
@@ -112,11 +173,19 @@ module Neo4j
|
|
112
173
|
end
|
113
174
|
|
114
175
|
def to_s
|
115
|
-
"NodeTraverser [from: #{@from.neo_id} depth: #{@depth}
|
176
|
+
"NodeTraverser [from: #{@from.neo_id} depth: #{@depth}"
|
116
177
|
end
|
117
178
|
|
118
179
|
|
119
180
|
# Creates a new relationship between given node and self
|
181
|
+
# It can create more then one relationship
|
182
|
+
#
|
183
|
+
# @example One outgoing relationships
|
184
|
+
# node.outgoing(:foo) << other_node
|
185
|
+
#
|
186
|
+
# @example Two outgoing relationships
|
187
|
+
# node.outgoing(:foo).outgoing(:bar) << other_node
|
188
|
+
#
|
120
189
|
# @param [Neo4j::Node] other_node the node to which we want to create a relationship
|
121
190
|
# @return (see #new)
|
122
191
|
def <<(other_node)
|
@@ -130,25 +199,49 @@ module Neo4j
|
|
130
199
|
end
|
131
200
|
|
132
201
|
# Creates a new relationship between self and given node.
|
202
|
+
# It can create more then one relationship
|
203
|
+
# This method is used by the <tt><<</tt> operator.
|
204
|
+
#
|
205
|
+
# @example create one relationship
|
206
|
+
# node.outgoing(:bar).new(other_node, rel_props)
|
207
|
+
#
|
208
|
+
# @example two relationships
|
209
|
+
# node.outgoing(:bar).outgoing(:foo).new(other_node, rel_props)
|
210
|
+
#
|
211
|
+
# @example both incoming and outgoing - two relationships
|
212
|
+
# node.both(:bar).new(other_node, rel_props)
|
213
|
+
#
|
214
|
+
# @see #<<
|
133
215
|
# @param [Hash] props properties of new relationship
|
134
216
|
# @return [Neo4j::Relationship] the created relationship
|
135
217
|
def new(other_node, props = {})
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
218
|
+
@outgoing_rel_types && @outgoing_rel_types.each { |type| _new_out(other_node, type, props) }
|
219
|
+
@incoming_rel_types && @incoming_rel_types.each { |type| _new_in(other_node, type, props) }
|
220
|
+
@both_rel_types && @both_rel_types.each { |type| _new_both(other_node, type, props) }
|
221
|
+
end
|
222
|
+
|
223
|
+
# @private
|
224
|
+
def _new_out(other_node, type, props)
|
225
|
+
@from.create_relationship_to(other_node, type_to_java(type)).update(props)
|
226
|
+
end
|
227
|
+
|
228
|
+
# @private
|
229
|
+
def _new_in(other_node, type, props)
|
230
|
+
other_node.create_relationship_to(@from, type_to_java(type)).update(props)
|
231
|
+
end
|
232
|
+
|
233
|
+
# @private
|
234
|
+
def _new_both(other_node, type, props)
|
235
|
+
_new_out(other_node, type, props)
|
236
|
+
_new_in(other_node, type, props)
|
144
237
|
end
|
145
238
|
|
146
239
|
# @param (see Neo4j::Core::Traversal#both)
|
147
240
|
# @see Neo4j::Core::Traversal#both
|
148
241
|
def both(type)
|
149
|
-
@
|
150
|
-
@
|
151
|
-
|
242
|
+
@both_rel_types ||= []
|
243
|
+
@both_rel_types << type
|
244
|
+
_add_rel(:both, type)
|
152
245
|
self
|
153
246
|
end
|
154
247
|
|
@@ -165,9 +258,9 @@ module Neo4j
|
|
165
258
|
# @return self
|
166
259
|
# @see Neo4j::Core::Traversal#outgoing
|
167
260
|
def outgoing(type)
|
168
|
-
@
|
169
|
-
@
|
170
|
-
|
261
|
+
@outgoing_rel_types ||= []
|
262
|
+
@outgoing_rel_types << type
|
263
|
+
_add_rel(:outgoing, type)
|
171
264
|
self
|
172
265
|
end
|
173
266
|
|
@@ -176,12 +269,19 @@ module Neo4j
|
|
176
269
|
# @return self
|
177
270
|
# @see Neo4j::Core::Traversal#incoming
|
178
271
|
def incoming(type)
|
179
|
-
@
|
180
|
-
@
|
181
|
-
|
272
|
+
@incoming_rel_types ||= []
|
273
|
+
@incoming_rel_types << type
|
274
|
+
_add_rel(:incoming, type)
|
182
275
|
self
|
183
276
|
end
|
184
277
|
|
278
|
+
# @private
|
279
|
+
def _add_rel(dir, type)
|
280
|
+
t = type_to_java(type)
|
281
|
+
d = dir_to_java(dir)
|
282
|
+
@td = @td ? @td.relationships(t, d) : Java::OrgNeo4jKernelImplTraversal::TraversalDescriptionImpl.new.breadth_first().relationships(t, d)
|
283
|
+
end
|
284
|
+
|
185
285
|
# Cuts of of parts of the traversal.
|
186
286
|
# @yield [path]
|
187
287
|
# @yieldparam [Java::OrgNeo4jGraphdb::Path] path the path which can be used to filter nodes
|
@@ -289,6 +389,7 @@ module Neo4j
|
|
289
389
|
end
|
290
390
|
|
291
391
|
end
|
392
|
+
|
292
393
|
end
|
293
394
|
end
|
294
395
|
end
|
data/lib/neo4j-core/version.rb
CHANGED
@@ -8,6 +8,13 @@ module Neo4j
|
|
8
8
|
def wrapper
|
9
9
|
self.class.wrapper(self)
|
10
10
|
end
|
11
|
+
|
12
|
+
# This can be implemented by a wrapper to returned the underlying java node or relationship.
|
13
|
+
# You can override this method in your own wrapper class.
|
14
|
+
# @return self
|
15
|
+
def java_entity
|
16
|
+
self
|
17
|
+
end
|
11
18
|
end
|
12
19
|
end
|
13
20
|
end
|
data/lib/neo4j/node.rb
CHANGED
@@ -9,9 +9,26 @@ module Neo4j
|
|
9
9
|
# *org.neo4j.kernel.impl.core.NodeProxy* object. This java object includes the same mixin as this class. The #class method on the java object
|
10
10
|
# returns Neo4j::Node in order to make it feel like an ordinary Ruby object.
|
11
11
|
#
|
12
|
+
# @example Create a node with one property (see {Neo4j::Core::Node::ClassMethods})
|
13
|
+
# Neo4j::Node.new(:name => 'andreas')
|
14
|
+
#
|
15
|
+
# @example Create a relationship (see {Neo4j::Core::Traversal})
|
16
|
+
# Neo4j::Node.new.outgoing(:friends) << Neo4j::Node.new
|
17
|
+
#
|
18
|
+
# @example Finding relationships (see {Neo4j::Core::Rels})
|
19
|
+
# node.rels(:outgoing, :friends)
|
20
|
+
#
|
21
|
+
# @example Lucene index (see {Neo4j::Core::Index})
|
22
|
+
# Neo4j::Node.trigger_on(:typex => 'MyTypeX')
|
23
|
+
# Neo4j::Node.index(:name)
|
24
|
+
# a = Neo4j::Node.new(:name => 'andreas', :typex => 'MyTypeX')
|
25
|
+
# # finish_tx
|
26
|
+
# Neo4j::Node.find(:name => 'andreas').first.should == a
|
27
|
+
#
|
12
28
|
class Node
|
13
29
|
extend Neo4j::Core::Node::ClassMethods
|
14
30
|
extend Neo4j::Core::Wrapper::ClassMethods
|
31
|
+
extend Neo4j::Core::Index::ClassMethods
|
15
32
|
|
16
33
|
include Neo4j::Core::Property
|
17
34
|
include Neo4j::Core::Rels
|
@@ -20,6 +37,11 @@ module Neo4j
|
|
20
37
|
include Neo4j::Core::Node
|
21
38
|
include Neo4j::Core::Wrapper
|
22
39
|
include Neo4j::Core::Property::Java # for documentation purpose only
|
40
|
+
include Neo4j::Core::Index
|
41
|
+
|
42
|
+
node_indexer do
|
43
|
+
index_names :exact => 'default_node_index_exact', :fulltext => 'default_node_index_fulltext'
|
44
|
+
end
|
23
45
|
|
24
46
|
class << self
|
25
47
|
|
@@ -33,6 +55,7 @@ module Neo4j
|
|
33
55
|
include Neo4j::Core::Equal
|
34
56
|
include Neo4j::Core::Node
|
35
57
|
include Neo4j::Core::Wrapper
|
58
|
+
include Neo4j::Core::Index
|
36
59
|
end
|
37
60
|
end
|
38
61
|
end
|
data/lib/neo4j/relationship.rb
CHANGED
@@ -29,17 +29,26 @@ module Neo4j
|
|
29
29
|
#
|
30
30
|
# node.outgoing(:friends) << other_node << yet_another_node
|
31
31
|
#
|
32
|
+
# @example lucene index
|
33
|
+
# Neo4j::Relationship.trigger_on(:typey => 123)
|
34
|
+
# Neo4j::Relationship.index(:name)
|
35
|
+
# a = Neo4j::Relationship.new(:friends, Neo4j::Node.new, Neo4j::Node.new, :typey => 123, :name => 'kalle')
|
36
|
+
# # Finish tx
|
37
|
+
# Neo4j::Relationship.find(:name => 'kalle').first.should be_nil
|
38
|
+
#
|
32
39
|
# @see http://api.neo4j.org/current/org/neo4j/graphdb/Relationship.html
|
33
40
|
#
|
34
41
|
class Relationship
|
35
42
|
extend Neo4j::Core::Relationship::ClassMethods
|
36
43
|
extend Neo4j::Core::Wrapper::ClassMethods
|
44
|
+
extend Neo4j::Core::Index::ClassMethods
|
37
45
|
|
38
46
|
include Neo4j::Core::Property
|
39
47
|
include Neo4j::Core::Equal
|
40
48
|
include Neo4j::Core::Relationship
|
41
49
|
include Neo4j::Core::Wrapper
|
42
50
|
include Neo4j::Core::Property::Java # for documentation purpose only
|
51
|
+
include Neo4j::Core::Index
|
43
52
|
|
44
53
|
|
45
54
|
# (see Neo4j::Core::Relationship::ClassMethods#new)
|
@@ -47,6 +56,10 @@ module Neo4j
|
|
47
56
|
end
|
48
57
|
|
49
58
|
|
59
|
+
rel_indexer do
|
60
|
+
index_names :exact => 'default_rel_index_exact', :fulltext => 'default_rel_index_fulltext'
|
61
|
+
end
|
62
|
+
|
50
63
|
class << self
|
51
64
|
def extend_java_class(java_clazz) #:nodoc:
|
52
65
|
java_clazz.class_eval do
|
@@ -54,6 +67,7 @@ module Neo4j
|
|
54
67
|
include Neo4j::Core::Equal
|
55
68
|
include Neo4j::Core::Relationship
|
56
69
|
include Neo4j::Core::Wrapper
|
70
|
+
include Neo4j::Core::Index
|
57
71
|
end
|
58
72
|
end
|
59
73
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: neo4j-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.10
|
6
6
|
platform: java
|
7
7
|
authors:
|
8
8
|
- Andreas Ronge
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-04-
|
13
|
+
date: 2012-04-17 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: neo4j-community
|