neography 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,9 +1,10 @@
1
1
  == Welcome to Neography
2
2
 
3
- Neography is a thin ruby wrapper to the Neo4j Rest API, for more information:
3
+ Neography is a thin Ruby wrapper to the Neo4j Rest API, for more information:
4
4
  * {Getting Started with Neo4j Server}[http://wiki.neo4j.org/content/Getting_Started_with_Neo4j_Server]
5
5
  * {Neo4j Rest API Reference}[http://components.neo4j.org/neo4j-rest/]
6
6
 
7
+ If you want to the full power of Neo4j, you will want to use JRuby and the excellent Neo4j.rb gem at https://github.com/andreasronge/neo4j
7
8
 
8
9
  === Installation
9
10
 
@@ -78,17 +79,42 @@ To Use:
78
79
  @neo.get_path(from, to, relationships, depth=4, algorithm="shortestPath") # finds the shortest path between two nodes
79
80
  @neo.get_paths(from, to, relationships, depth=3, algorithm="allPaths") # finds all paths between two nodes
80
81
 
82
+ nodes = @neo.traverse(id, # the id of the node where the traversal starts
83
+ "nodes", # return_type (can be "nodes", "relationships" or "paths"
84
+ {"order" => "breadth first", # "breadth first" or "depth first" traversal order
85
+ "uniqueness" => "node global", # See Uniqueness in API documentation for options.
86
+ "relationships" => [{"type"=> "roommates", # A hash containg a description of the traversal
87
+ "direction" => "all"}, # two relationships.
88
+ {"type"=> "friends", #
89
+ "direction" => "out"}], #
90
+ "prune evaluator" => {"language" => "javascript", # A prune evaluator (when to stop traversing)
91
+ "body" => "position.endNode().getProperty('age') < 21;"
92
+ "return filter" => {"language" => "builtin", # "all" or "all but start node"
93
+ "name" => "all"},
94
+ "depth" => 4})
95
+
96
+ # "depth" is a short-hand way of specifying a prune evaluator which prunes after a certain depth.
97
+ # If not specified a depth of 1 is used and if a "prune evaluator" is specified instead of a depth, no depth limit is set.
98
+
99
+ Please see the specs for more examples.
100
+
101
+ See Neo4j API for:
102
+ * {Order}[http://components.neo4j.org/neo4j-examples/1.2.M04/apidocs/org/neo4j/graphdb/Traverser.Order.html]
103
+ * {Uniqueness}[http://components.neo4j.org/neo4j-examples/1.2.M04/apidocs/org/neo4j/kernel/Uniqueness.html]
104
+ * {Prune Evaluator}[http://components.neo4j.org/neo4j-examples/1.2.M04/apidocs/org/neo4j/graphdb/StopEvaluator.html]
105
+ * {Return Filter}[http://components.neo4j.org/neo4j-examples/1.2.M04/apidocs/org/neo4j/graphdb/ReturnableEvaluator.html]
106
+
81
107
  === To Do
82
108
 
83
- Path tests
84
- Traverse tests
85
- @neo.traverse()
86
- examples
109
+ * More tests
110
+ * examples
111
+ * batch import with typhoeus ?
112
+ * create proper objects for Node and Relationship
87
113
 
88
114
  === License
89
115
 
90
116
  * Neography - MIT, see the LICENSE file http://github.com/maxdemarzi/neography/tree/master/LICENSE.
91
117
  * Lucene - Apache, see http://lucene.apache.org/java/docs/features.html
92
- * Neo4j - Dual free software/commercial license, see http://neo4j.org/
118
+ * Neo4j - Dual free software/commercial license, see http://neo4j.org
93
119
 
94
120
 
@@ -161,6 +161,16 @@ module Neography
161
161
  index
162
162
  end
163
163
 
164
+ def traverse(id, return_type, description)
165
+ options = { :body => {"order" => get_order(description["order"]),
166
+ "uniqueness" => get_uniqueness(description["uniqueness"]),
167
+ "relationships" => description["relationships"],
168
+ "prune evaluator" => description["prune evaluator"],
169
+ "return filter" => description["return filter"],
170
+ "max depth" => get_depth(description["depth"]), }.to_json, :headers => {'Content-Type' => 'application/json'} }
171
+ traversal = post("/node/#{id}/traverse/#{get_type(return_type)}", options) || Array.new
172
+ end
173
+
164
174
  def get_path(from, to, relationships, depth=1, algorithm="shortestPath")
165
175
  options = { :body => {"to" => self.configuration + "/node/#{to}", "relationships" => relationships, "max depth" => depth, "algorithm" => get_algorithm(algorithm) }.to_json, :headers => {'Content-Type' => 'application/json'} }
166
176
  path = post("/node/#{from}/path", options) || Hash.new
@@ -237,5 +247,49 @@ module Neography
237
247
  end
238
248
  end
239
249
 
250
+ def get_order(order)
251
+ case order
252
+ when :breadth, "breadth", "breadth first", "breadthFirst", :wide, "wide"
253
+ "breadth first"
254
+ else
255
+ "depth first"
256
+ end
257
+ end
258
+
259
+ def get_type(type)
260
+ case type
261
+ when :node, "nodes", :nodes, "nodes"
262
+ "node"
263
+ when :relationship, "relationship", :relationships, "relationships"
264
+ "relationship"
265
+ else
266
+ "path"
267
+ end
268
+ end
269
+
270
+ def get_uniqueness(uniqueness)
271
+ case uniqueness
272
+ when :nodeglobal, "node global", "nodeglobal", "node_global"
273
+ "node global"
274
+ when :nodepath, "node path", "nodepath", "node_path"
275
+ "node path"
276
+ when :noderecent, "node recent", "noderecent", "node_recent"
277
+ "node recent"
278
+ when :relationshipglobal, "relationship global", "relationshipglobal", "relationship_global"
279
+ "relationship global"
280
+ when :relationshippath, "relationship path", "relationshippath", "relationship_path"
281
+ "relationship path"
282
+ when :relationshiprecent, "relationship recent", "relationshiprecent", "relationship_recent"
283
+ "relationship recent"
284
+ else
285
+ "none"
286
+ end
287
+ end
288
+
289
+ def get_depth(depth)
290
+ return 1 if depth.to_i == 0
291
+ depth.to_i
292
+ end
293
+
240
294
  end
241
295
  end
@@ -1,3 +1,3 @@
1
1
  module Neography
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -19,41 +19,235 @@ describe Neography::Rest do
19
19
  end
20
20
 
21
21
  it "can get the shortest path between two nodes" do
22
- pending
22
+ new_node1 = @neo.create_node
23
+ new_node1[:id] = new_node1["self"].split('/').last
24
+ new_node2 = @neo.create_node
25
+ new_node2[:id] = new_node2["self"].split('/').last
26
+ new_node3 = @neo.create_node
27
+ new_node3[:id] = new_node3["self"].split('/').last
28
+ new_node4 = @neo.create_node
29
+ new_node4[:id] = new_node4["self"].split('/').last
30
+ new_node5 = @neo.create_node
31
+ new_node5[:id] = new_node5["self"].split('/').last
32
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
33
+ @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
34
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
35
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
36
+ @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
37
+ path = @neo.get_path(new_node1[:id], new_node5[:id], {"type"=> "friends", "direction" => "out"}, depth=3, algorithm="shortestPath")
38
+ path["start"].should == new_node1["self"]
39
+ path["end"].should == new_node5["self"]
40
+ path["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node5["self"]]
23
41
  end
24
42
 
25
43
  it "can get a simple path between two nodes" do
26
- pending
44
+ new_node1 = @neo.create_node
45
+ new_node1[:id] = new_node1["self"].split('/').last
46
+ new_node2 = @neo.create_node
47
+ new_node2[:id] = new_node2["self"].split('/').last
48
+ new_node3 = @neo.create_node
49
+ new_node3[:id] = new_node3["self"].split('/').last
50
+ new_node4 = @neo.create_node
51
+ new_node4[:id] = new_node4["self"].split('/').last
52
+ new_node5 = @neo.create_node
53
+ new_node5[:id] = new_node5["self"].split('/').last
54
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
55
+ @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
56
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
57
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
58
+ @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
59
+ path = @neo.get_path(new_node1[:id], new_node5[:id], {"type"=> "friends", "direction" => "out"}, depth=3, algorithm="simplePaths")
60
+ path["start"].should == new_node1["self"]
61
+ path["end"].should == new_node5["self"]
62
+ path["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node5["self"]]
27
63
  end
28
64
 
29
- it "can get a path between two nodes of max depth 3" do
30
- pending
65
+ it "fails to get a path between two nodes 3 nodes apart when using max depth of 2" do
66
+ new_node1 = @neo.create_node
67
+ new_node1[:id] = new_node1["self"].split('/').last
68
+ new_node2 = @neo.create_node
69
+ new_node2[:id] = new_node2["self"].split('/').last
70
+ new_node3 = @neo.create_node
71
+ new_node3[:id] = new_node3["self"].split('/').last
72
+ new_node4 = @neo.create_node
73
+ new_node4[:id] = new_node4["self"].split('/').last
74
+ new_node5 = @neo.create_node
75
+ new_node5[:id] = new_node5["self"].split('/').last
76
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
77
+ @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
78
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
79
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
80
+ @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
81
+ path = @neo.get_path(new_node1[:id], new_node5[:id], {"type"=> "friends", "direction" => "out"}, depth=2, algorithm="shortestPath")
82
+ path["start"].should be_nil
83
+ path["end"].should be_nil
31
84
  end
32
85
 
33
86
  it "can get a path between two nodes of a specific relationship" do
34
- pending
87
+ new_node1 = @neo.create_node
88
+ new_node1[:id] = new_node1["self"].split('/').last
89
+ new_node2 = @neo.create_node
90
+ new_node2[:id] = new_node2["self"].split('/').last
91
+ new_node3 = @neo.create_node
92
+ new_node3[:id] = new_node3["self"].split('/').last
93
+ new_node4 = @neo.create_node
94
+ new_node4[:id] = new_node4["self"].split('/').last
95
+ new_node5 = @neo.create_node
96
+ new_node5[:id] = new_node5["self"].split('/').last
97
+ @neo.create_relationship("classmates", new_node1[:id], new_node2[:id])
98
+ @neo.create_relationship("classmates", new_node2[:id], new_node5[:id])
99
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
100
+ @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
101
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
102
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
103
+ path = @neo.get_path(new_node1[:id], new_node5[:id], {"type"=> "friends", "direction" => "out"}, depth=4, algorithm="shortestPath")
104
+ path["start"].should == new_node1["self"]
105
+ path["end"].should == new_node5["self"]
106
+ path["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node4["self"], new_node5["self"]]
35
107
  end
36
108
  end
37
109
 
38
110
  describe "get paths" do
39
111
  it "can get the shortest paths between two nodes" do
40
- pending
112
+ new_node1 = @neo.create_node
113
+ new_node1[:id] = new_node1["self"].split('/').last
114
+ new_node2 = @neo.create_node
115
+ new_node2[:id] = new_node2["self"].split('/').last
116
+ new_node3 = @neo.create_node
117
+ new_node3[:id] = new_node3["self"].split('/').last
118
+ new_node4 = @neo.create_node
119
+ new_node4[:id] = new_node4["self"].split('/').last
120
+ new_node5 = @neo.create_node
121
+ new_node5[:id] = new_node5["self"].split('/').last
122
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
123
+ @neo.create_relationship("friends", new_node2[:id], new_node5[:id])
124
+ @neo.create_relationship("friends", new_node1[:id], new_node3[:id])
125
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
126
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
127
+ @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
128
+ paths = @neo.get_paths(new_node1[:id], new_node5[:id], {"type"=> "friends", "direction" => "out"}, depth=4, algorithm="shortestPath")
129
+ paths.length.should == 2
130
+ paths[0]["length"].should == 2
131
+ paths[0]["start"].should == new_node1["self"]
132
+ paths[0]["end"].should == new_node5["self"]
133
+ paths[1]["length"].should == 2
134
+ paths[1]["start"].should == new_node1["self"]
135
+ paths[1]["end"].should == new_node5["self"]
41
136
  end
42
137
 
43
138
  it "can get all paths between two nodes" do
44
- pending
139
+ new_node1 = @neo.create_node
140
+ new_node1[:id] = new_node1["self"].split('/').last
141
+ new_node2 = @neo.create_node
142
+ new_node2[:id] = new_node2["self"].split('/').last
143
+ new_node3 = @neo.create_node
144
+ new_node3[:id] = new_node3["self"].split('/').last
145
+ new_node4 = @neo.create_node
146
+ new_node4[:id] = new_node4["self"].split('/').last
147
+ new_node5 = @neo.create_node
148
+ new_node5[:id] = new_node5["self"].split('/').last
149
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
150
+ @neo.create_relationship("friends", new_node2[:id], new_node5[:id])
151
+ @neo.create_relationship("friends", new_node1[:id], new_node3[:id])
152
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
153
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
154
+ @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
155
+ paths = @neo.get_paths(new_node1[:id], new_node5[:id], {"type"=> "friends", "direction" => "out"}, depth=4, algorithm="allPaths")
156
+ paths.length.should == 3
157
+ paths[0]["length"].should == 2
158
+ paths[0]["start"].should == new_node1["self"]
159
+ paths[0]["end"].should == new_node5["self"]
160
+ paths[1]["length"].should == 3
161
+ paths[1]["start"].should == new_node1["self"]
162
+ paths[1]["end"].should == new_node5["self"]
163
+ paths[2]["length"].should == 2
164
+ paths[2]["start"].should == new_node1["self"]
165
+ paths[2]["end"].should == new_node5["self"]
45
166
  end
46
167
 
47
168
  it "can get all simple paths between two nodes" do
48
- pending
169
+ new_node1 = @neo.create_node
170
+ new_node1[:id] = new_node1["self"].split('/').last
171
+ new_node2 = @neo.create_node
172
+ new_node2[:id] = new_node2["self"].split('/').last
173
+ new_node3 = @neo.create_node
174
+ new_node3[:id] = new_node3["self"].split('/').last
175
+ new_node4 = @neo.create_node
176
+ new_node4[:id] = new_node4["self"].split('/').last
177
+ new_node5 = @neo.create_node
178
+ new_node5[:id] = new_node5["self"].split('/').last
179
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
180
+ @neo.create_relationship("friends", new_node2[:id], new_node1[:id])
181
+ @neo.create_relationship("friends", new_node2[:id], new_node5[:id])
182
+ @neo.create_relationship("friends", new_node1[:id], new_node3[:id])
183
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
184
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
185
+ @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
186
+ paths = @neo.get_paths(new_node1[:id], new_node5[:id], {"type"=> "friends", "direction" => "out"}, depth=4, algorithm="allSimplePaths")
187
+ paths.length.should == 3
188
+ paths[0]["length"].should == 2
189
+ paths[0]["start"].should == new_node1["self"]
190
+ paths[0]["end"].should == new_node5["self"]
191
+ paths[1]["length"].should == 3
192
+ paths[1]["start"].should == new_node1["self"]
193
+ paths[1]["end"].should == new_node5["self"]
194
+ paths[2]["length"].should == 2
195
+ paths[2]["start"].should == new_node1["self"]
196
+ paths[2]["end"].should == new_node5["self"]
49
197
  end
50
198
 
51
- it "can get paths between two nodes of max depth 3" do
52
- pending
53
- end
199
+ it "can get paths between two nodes of max depth 2" do
200
+ new_node1 = @neo.create_node
201
+ new_node1[:id] = new_node1["self"].split('/').last
202
+ new_node2 = @neo.create_node
203
+ new_node2[:id] = new_node2["self"].split('/').last
204
+ new_node3 = @neo.create_node
205
+ new_node3[:id] = new_node3["self"].split('/').last
206
+ new_node4 = @neo.create_node
207
+ new_node4[:id] = new_node4["self"].split('/').last
208
+ new_node5 = @neo.create_node
209
+ new_node5[:id] = new_node5["self"].split('/').last
210
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
211
+ @neo.create_relationship("friends", new_node2[:id], new_node5[:id])
212
+ @neo.create_relationship("friends", new_node1[:id], new_node3[:id])
213
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
214
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
215
+ @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
216
+ paths = @neo.get_paths(new_node1[:id], new_node5[:id], {"type"=> "friends", "direction" => "out"}, depth=2, algorithm="allPaths")
217
+ paths.length.should == 2
218
+ paths[0]["length"].should == 2
219
+ paths[0]["start"].should == new_node1["self"]
220
+ paths[0]["end"].should == new_node5["self"]
221
+ paths[1]["length"].should == 2
222
+ paths[1]["start"].should == new_node1["self"]
223
+ paths[1]["end"].should == new_node5["self"] end
54
224
 
55
225
  it "can get paths between two nodes of a specific relationship" do
56
- pending
226
+ new_node1 = @neo.create_node
227
+ new_node1[:id] = new_node1["self"].split('/').last
228
+ new_node2 = @neo.create_node
229
+ new_node2[:id] = new_node2["self"].split('/').last
230
+ new_node3 = @neo.create_node
231
+ new_node3[:id] = new_node3["self"].split('/').last
232
+ new_node4 = @neo.create_node
233
+ new_node4[:id] = new_node4["self"].split('/').last
234
+ new_node5 = @neo.create_node
235
+ new_node5[:id] = new_node5["self"].split('/').last
236
+ @neo.create_relationship("classmates", new_node1[:id], new_node2[:id])
237
+ @neo.create_relationship("classmates", new_node2[:id], new_node5[:id])
238
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
239
+ @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
240
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
241
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
242
+ @neo.create_relationship("classmates", new_node1[:id], new_node3[:id])
243
+ @neo.create_relationship("classmates", new_node3[:id], new_node5[:id])
244
+ paths = @neo.get_paths(new_node1[:id], new_node5[:id], {"type"=> "classmates", "direction" => "out"}, depth=4, algorithm="allPaths")
245
+ paths[0]["length"].should == 2
246
+ paths[0]["start"].should == new_node1["self"]
247
+ paths[0]["end"].should == new_node5["self"]
248
+ paths[1]["length"].should == 2
249
+ paths[1]["start"].should == new_node1["self"]
250
+ paths[1]["end"].should == new_node5["self"]
57
251
  end
58
252
 
59
253
  end
@@ -0,0 +1,230 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe Neography::Rest do
4
+ before(:each) do
5
+ @neo = Neography::Rest.new
6
+ end
7
+
8
+ describe "traverse" do
9
+ it "can traverse the graph and return nodes" do
10
+ new_node1 = @neo.create_node
11
+ new_node1[:id] = new_node1["self"].split('/').last
12
+ new_node2 = @neo.create_node
13
+ new_node2[:id] = new_node2["self"].split('/').last
14
+ new_node3 = @neo.create_node
15
+ new_node3[:id] = new_node3["self"].split('/').last
16
+ new_node4 = @neo.create_node
17
+ new_node4[:id] = new_node4["self"].split('/').last
18
+ new_node5 = @neo.create_node
19
+ new_node5[:id] = new_node5["self"].split('/').last
20
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
21
+ @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
22
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
23
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
24
+ @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
25
+ nodes = @neo.traverse(new_node1[:id], "nodes", {"relationships" => {"type"=> "friends", "direction" => "out"}, "depth" => 4} )
26
+ nodes.should_not be_nil
27
+ nodes[0]["self"].should == new_node2["self"]
28
+ nodes[1]["self"].should == new_node3["self"]
29
+ nodes[2]["self"].should == new_node4["self"]
30
+ nodes[3]["self"].should == new_node5["self"]
31
+ end
32
+
33
+ it "can traverse the graph and return relationships" do
34
+ new_node1 = @neo.create_node
35
+ new_node1[:id] = new_node1["self"].split('/').last
36
+ new_node2 = @neo.create_node
37
+ new_node2[:id] = new_node2["self"].split('/').last
38
+ new_node3 = @neo.create_node
39
+ new_node3[:id] = new_node3["self"].split('/').last
40
+ new_node4 = @neo.create_node
41
+ new_node4[:id] = new_node4["self"].split('/').last
42
+ new_node5 = @neo.create_node
43
+ new_node5[:id] = new_node5["self"].split('/').last
44
+
45
+ new_relationship1= @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
46
+ new_relationship2= @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
47
+ new_relationship3= @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
48
+ new_relationship4= @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
49
+ new_relationship5= @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
50
+
51
+ relationships = @neo.traverse(new_node1[:id], "relationships", {"relationships" => {"type"=> "friends", "direction" => "out"}, "depth" => 4} )
52
+ relationships.should_not be_nil
53
+
54
+ relationships[0]["self"].should == new_relationship1["self"]
55
+ relationships[1]["self"].should == new_relationship2["self"]
56
+ relationships[2]["self"].should == new_relationship3["self"]
57
+ relationships[3]["self"].should == new_relationship4["self"]
58
+ end
59
+
60
+ it "can traverse the graph and return paths" do
61
+ new_node1 = @neo.create_node
62
+ new_node1[:id] = new_node1["self"].split('/').last
63
+ new_node2 = @neo.create_node
64
+ new_node2[:id] = new_node2["self"].split('/').last
65
+ new_node3 = @neo.create_node
66
+ new_node3[:id] = new_node3["self"].split('/').last
67
+ new_node4 = @neo.create_node
68
+ new_node4[:id] = new_node4["self"].split('/').last
69
+ new_node5 = @neo.create_node
70
+ new_node5[:id] = new_node5["self"].split('/').last
71
+
72
+ new_relationship1= @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
73
+ new_relationship2= @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
74
+ new_relationship3= @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
75
+ new_relationship4= @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
76
+ new_relationship5= @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
77
+
78
+ paths = @neo.traverse(new_node1[:id], "paths", {"relationships" => {"type"=> "friends", "direction" => "out"}, "depth" => 4} )
79
+ paths.should_not be_nil
80
+
81
+ paths[0]["nodes"].should == [new_node1["self"], new_node2["self"]]
82
+ paths[1]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"]]
83
+ paths[2]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node4["self"]]
84
+ paths[3]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node4["self"], new_node5["self"]]
85
+ end
86
+
87
+ it "can traverse the graph up to a certain depth" do
88
+ new_node1 = @neo.create_node
89
+ new_node1[:id] = new_node1["self"].split('/').last
90
+ new_node2 = @neo.create_node
91
+ new_node2[:id] = new_node2["self"].split('/').last
92
+ new_node3 = @neo.create_node
93
+ new_node3[:id] = new_node3["self"].split('/').last
94
+ new_node4 = @neo.create_node
95
+ new_node4[:id] = new_node4["self"].split('/').last
96
+ new_node5 = @neo.create_node
97
+ new_node5[:id] = new_node5["self"].split('/').last
98
+
99
+ new_relationship1= @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
100
+ new_relationship2= @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
101
+ new_relationship3= @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
102
+ new_relationship4= @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
103
+ new_relationship5= @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
104
+
105
+ paths = @neo.traverse(new_node1[:id], "paths", {"relationships" => {"type"=> "friends", "direction" => "out"}, "depth" => 3} )
106
+ paths.should_not be_nil
107
+
108
+ paths[0]["nodes"].should == [new_node1["self"], new_node2["self"]]
109
+ paths[1]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"]]
110
+ paths[2]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node4["self"]]
111
+ paths[3]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node5["self"]]
112
+ end
113
+
114
+ it "can traverse the graph in a certain order" do
115
+ new_node1 = @neo.create_node
116
+ new_node1[:id] = new_node1["self"].split('/').last
117
+ new_node2 = @neo.create_node
118
+ new_node2[:id] = new_node2["self"].split('/').last
119
+ new_node3 = @neo.create_node
120
+ new_node3[:id] = new_node3["self"].split('/').last
121
+ new_node4 = @neo.create_node
122
+ new_node4[:id] = new_node4["self"].split('/').last
123
+ new_node5 = @neo.create_node
124
+ new_node5[:id] = new_node5["self"].split('/').last
125
+
126
+ new_relationship1= @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
127
+ new_relationship2= @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
128
+ new_relationship3= @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
129
+ new_relationship4= @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
130
+ new_relationship5= @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
131
+
132
+ paths = @neo.traverse(new_node1[:id], "paths", {"order" => "breadth first", "relationships" => {"type"=> "friends", "direction" => "out"}, "depth" => 4} )
133
+ paths.should_not be_nil
134
+
135
+ paths[0]["nodes"].should == [new_node1["self"], new_node2["self"]]
136
+ paths[1]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"]]
137
+ paths[2]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node4["self"]]
138
+ paths[3]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node5["self"]]
139
+ end
140
+
141
+ it "can traverse the graph with a specific uniqueness" do
142
+ new_node1 = @neo.create_node
143
+ new_node1[:id] = new_node1["self"].split('/').last
144
+ new_node2 = @neo.create_node
145
+ new_node2[:id] = new_node2["self"].split('/').last
146
+ new_node3 = @neo.create_node
147
+ new_node3[:id] = new_node3["self"].split('/').last
148
+ new_node4 = @neo.create_node
149
+ new_node4[:id] = new_node4["self"].split('/').last
150
+ new_node5 = @neo.create_node
151
+ new_node5[:id] = new_node5["self"].split('/').last
152
+
153
+ new_relationship1= @neo.create_relationship("roommates", new_node1[:id], new_node2[:id])
154
+ new_relationship2= @neo.create_relationship("roommates", new_node2[:id], new_node3[:id])
155
+ new_relationship1= @neo.create_relationship("friends", new_node3[:id], new_node2[:id])
156
+ new_relationship2= @neo.create_relationship("friends", new_node2[:id], new_node5[:id])
157
+ new_relationship3= @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
158
+ new_relationship4= @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
159
+ new_relationship5= @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
160
+
161
+ paths = @neo.traverse(new_node1[:id], "paths", {"order" => "breadth first", "uniqueness" => "node global", "relationships" => [{"type"=> "roommates", "direction" => "all"},{"type"=> "friends", "direction" => "out"}], "depth" => 4} )
162
+ paths.should_not be_nil
163
+
164
+ paths[0]["nodes"].should == [new_node1["self"], new_node2["self"]]
165
+ paths[1]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"]]
166
+ paths[2]["nodes"].should == [new_node1["self"], new_node2["self"], new_node5["self"]]
167
+ paths[3]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"], new_node4["self"]]
168
+ end
169
+
170
+ it "can traverse the graph with a prune evaluator" do
171
+ new_node1 = @neo.create_node("age" => 31, "name" => "Max")
172
+ new_node1[:id] = new_node1["self"].split('/').last
173
+ new_node2 = @neo.create_node("age" => 30, "name" => "Helene")
174
+ new_node2[:id] = new_node2["self"].split('/').last
175
+ new_node3 = @neo.create_node("age" => 17, "name" => "Alex")
176
+ new_node3[:id] = new_node3["self"].split('/').last
177
+ new_node4 = @neo.create_node("age" => 24, "name" => "Eric")
178
+ new_node4[:id] = new_node4["self"].split('/').last
179
+ new_node5 = @neo.create_node("age" => 32, "name" => "Leslie")
180
+ new_node5[:id] = new_node5["self"].split('/').last
181
+
182
+ new_relationship1= @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
183
+ new_relationship2= @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
184
+ new_relationship3= @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
185
+ new_relationship4= @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
186
+ new_relationship5= @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
187
+
188
+ paths = @neo.traverse(new_node1[:id],
189
+ "paths",
190
+ {"relationships" => {"type"=> "friends", "direction" => "out"},
191
+ "depth" => 3,
192
+ "prune evaluator" => {"language" => "javascript", "body" => "position.endNode().getProperty('age') < 21;"
193
+ }} )
194
+ paths.should_not be_nil
195
+ paths[0]["nodes"].should == [new_node1["self"], new_node2["self"]]
196
+ paths[1]["nodes"].should == [new_node1["self"], new_node2["self"], new_node3["self"]]
197
+ paths[2].should be_nil
198
+ end
199
+
200
+ it "can traverse the graph with a return filter" do
201
+ new_node1 = @neo.create_node
202
+ new_node1[:id] = new_node1["self"].split('/').last
203
+ new_node2 = @neo.create_node
204
+ new_node2[:id] = new_node2["self"].split('/').last
205
+ new_node3 = @neo.create_node
206
+ new_node3[:id] = new_node3["self"].split('/').last
207
+ new_node4 = @neo.create_node
208
+ new_node4[:id] = new_node4["self"].split('/').last
209
+ new_node5 = @neo.create_node
210
+ new_node5[:id] = new_node5["self"].split('/').last
211
+ @neo.create_relationship("friends", new_node1[:id], new_node2[:id])
212
+ @neo.create_relationship("friends", new_node2[:id], new_node3[:id])
213
+ @neo.create_relationship("friends", new_node3[:id], new_node4[:id])
214
+ @neo.create_relationship("friends", new_node4[:id], new_node5[:id])
215
+ @neo.create_relationship("friends", new_node3[:id], new_node5[:id])
216
+ nodes = @neo.traverse(new_node1[:id], "nodes", {"relationships" => {"type"=> "friends", "direction" => "out"},
217
+ "return filter" => {"language" => "builtin", "name" => "all"},
218
+ "depth" => 4} )
219
+ nodes.should_not be_nil
220
+ nodes[0]["self"].should == new_node1["self"]
221
+ nodes[1]["self"].should == new_node2["self"]
222
+ nodes[2]["self"].should == new_node3["self"]
223
+ nodes[3]["self"].should == new_node4["self"]
224
+ nodes[4]["self"].should == new_node5["self"]
225
+ end
226
+
227
+
228
+ end
229
+
230
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Max De Marzi
@@ -108,7 +108,6 @@ files:
108
108
  - README.rdoc
109
109
  - Rakefile
110
110
  - lib/neography.rb
111
- - lib/neography/config.rb
112
111
  - lib/neography/rest.rb
113
112
  - lib/neography/version.rb
114
113
  - neography.gemspec
@@ -116,6 +115,7 @@ files:
116
115
  - spec/integration/rest_node_spec.rb
117
116
  - spec/integration/rest_path_spec.rb
118
117
  - spec/integration/rest_relationship_spec.rb
118
+ - spec/integration/rest_traverse_spec.rb
119
119
  - spec/spec_helper.rb
120
120
  - spec/support/fake_root_spec.rb
121
121
  has_rdoc: true
@@ -1,152 +0,0 @@
1
- module Neography
2
-
3
- # == Keeps configuration for neography
4
- #
5
- # The most important configuration options are <tt>Neograophy::Config[:server]</tt> and <tt>Neograophy::Config[:port]</tt> which are
6
- # used to locate where the neo4j database and is stored on the network.
7
- # If these options are not supplied then the default of localhost:9999 will be used.
8
- #
9
- # ==== Default Configurations
10
- # <tt>:protocol</tt>:: default <tt>http://</tt> protocol to use (can be https://)
11
- # <tt>:server</tt>:: default <tt>localhost</tt> where the database is stored on the network
12
- # <tt>:port</tt>:: default <tt>7474</tt> what port is listening
13
- #
14
- class Config
15
- # This code is copied from merb-core/config.rb.
16
- class << self
17
- # Returns the hash of default config values for neography
18
- #
19
- # ==== Returns
20
- # Hash:: The defaults for the config.
21
- def defaults
22
- @defaults ||= {
23
- :protocol => 'http://',
24
- :server => 'localhost',
25
- :port => '7474'
26
- }
27
- end
28
-
29
-
30
- # Yields the configuration.
31
- #
32
- # ==== Block parameters
33
- # c :: The configuration parameters, a hash.
34
- #
35
- # ==== Examples
36
- # Neography::Config.use do |config|
37
- # config[:server] = '192.168.1.13'
38
- # end
39
- #
40
- # ==== Returns
41
- # nil
42
- def use
43
- @configuration ||= {}
44
- yield @configuration
45
- nil
46
- end
47
-
48
-
49
- # Set the value of a config entry.
50
- #
51
- # ==== Parameters
52
- # key :: The key to set the parameter for.
53
- # val :: The value of the parameter.
54
- #
55
- def []=(key, val)
56
- (@configuration ||= setup)[key] = val
57
- end
58
-
59
-
60
- # Gets the the value of a config entry
61
- #
62
- # ==== Parameters
63
- # key:: The key of the config entry value we want
64
- #
65
- def [](key)
66
- (@configuration ||= setup)[key]
67
- end
68
-
69
-
70
- # Remove the value of a config entry.
71
- #
72
- # ==== Parameters
73
- # key<Object>:: The key of the parameter to delete.
74
- #
75
- # ==== Returns
76
- # The value of the removed entry.
77
- #
78
- def delete(key)
79
- @configuration.delete(key)
80
- end
81
-
82
-
83
- # Remove all configuration. This can be useful for testing purpose.
84
- #
85
- #
86
- # ==== Returns
87
- # nil
88
- #
89
- def delete_all
90
- @configuration = nil
91
- end
92
-
93
-
94
- # Retrieve the value of a config entry, returning the provided default if the key is not present
95
- #
96
- # ==== Parameters
97
- # key:: The key to retrieve the parameter for.
98
- # default::The default value to return if the parameter is not set.
99
- #
100
- # ==== Returns
101
- # The value of the configuration parameter or the default.
102
- #
103
- def fetch(key, default)
104
- @configuration.fetch(key, default)
105
- end
106
-
107
- # Sets up the configuration
108
- #
109
- # ==== Returns
110
- # The configuration as a hash.
111
- #
112
- def setup()
113
- @configuration = {}
114
- @configuration.merge!(defaults)
115
- @configuration
116
- end
117
-
118
-
119
- # Returns the configuration as a hash.
120
- #
121
- # ==== Returns
122
- # The config as a hash.
123
- #
124
- def to_hash
125
- @configuration
126
- end
127
-
128
- # Returns the config as YAML.
129
- #
130
- # ==== Returns
131
- # The config as YAML.
132
- #
133
- def to_yaml
134
- require "yaml"
135
- @configuration.to_yaml
136
- end
137
-
138
- # Returns the configuration as a string.
139
- #
140
- # ==== Returns
141
- # The config as a string.
142
- #
143
- def to_s
144
- setup
145
- @configuration[:protocol] + @configuration[:server].to_s + ':' + @configuration[:port].to_s
146
- end
147
-
148
-
149
- end
150
- end
151
-
152
- end