neography 1.3.6 → 1.3.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c0370d9441fe781940dd20f4a89eac1306299d8a
4
- data.tar.gz: 51f228c713783eac9783df52a61676ddead5435c
3
+ metadata.gz: c8915c7b2abbc72fbe16cb33d50b7e80d0c71b15
4
+ data.tar.gz: 2933f91d72dd64da8a60f9a2155068b9baacff32
5
5
  SHA512:
6
- metadata.gz: ac5122807662830386f371b96335e98b6d3b967bd871dbe8c4f5e53de41ece3638e251d05d891a9323f5551c80d4ae3e1857307c23573c56bf414416a3e4445e
7
- data.tar.gz: 6e8b5282ece9f8b52c30c5b599a7ea7ef1d08facb786d34b62be2078e836214f51e4782123d88295de50d71b49abc4f2011f30f45a86db42a8eda51b99ba514a
6
+ metadata.gz: 89c856460ee6365d4e24ebb270349b2fba5f8e4430afba1ba093ba3f85eed84bb524881e19a3f0e9e20792a57d2e5d930ec473b0234af1c3034cdafd136b133c
7
+ data.tar.gz: e7bcf2213babefd378c24c910163795c680a49a8bbb9cec62cb46064cb5f9506adbd16d7e58cee9ec412529f3ff74055527f998d3207793ab3877121c221dc11
@@ -1,4 +1,4 @@
1
- script: "bundle exec rake neo4j:install['enterprise','2.0.0'] neo4j:start spec --trace"
1
+ script: "bundle exec rake neo4j:install['enterprise','2.0.0'] neo4j:get_spatial neo4j:start spec --trace"
2
2
  language: ruby
3
3
  rvm:
4
4
  - 1.9.3
data/README.md CHANGED
@@ -138,12 +138,29 @@ node2 = @neo.create_node("age" => 33, "name" => "Roel")
138
138
  @neo.add_node_to_index("people", "name", "max", node1)
139
139
  @neo.get_node_index("people", "name", "max")
140
140
 
141
- # Cypher queries:
142
- @neo.execute_query("start n=node(0) return n")
143
-
144
141
  # Batches:
145
142
  @neo.batch [:create_node, {"name" => "Max"}],
146
143
  [:create_node, {"name" => "Marc"}]
144
+
145
+ # Cypher queries:
146
+ @neo.execute_query("start n=node(0) return n")
147
+
148
+ ```
149
+
150
+ You can also use the [cypher gem](https://github.com/andreasronge/neo4j-cypher) instead of writing cypher as text.
151
+
152
+
153
+ ```
154
+ node(1).outgoing(rel(:friends).where{|r| r[:since] == 1994})
155
+ ```
156
+
157
+ would become:
158
+
159
+ ```
160
+ START me=node(1)
161
+ MATCH (me)-[friend_rel:`friends`]->(friends)
162
+ WHERE (friend_rel.since = 1994)
163
+ RETURN friends
147
164
  ```
148
165
 
149
166
  This is just a small sample of the full API, see the [Wiki documentation](https://github.com/maxdemarzi/neography/wiki) for the full API.
@@ -28,6 +28,7 @@ require 'neography/rest/extensions'
28
28
  require 'neography/rest/batch'
29
29
  require 'neography/rest/clean'
30
30
  require 'neography/rest/transactions'
31
+ require 'neography/rest/spatial'
31
32
 
32
33
  require 'neography/errors'
33
34
 
@@ -69,6 +70,7 @@ module Neography
69
70
  @batch = Batch.new(@connection)
70
71
  @clean = Clean.new(@connection)
71
72
  @transactions = Transactions.new(@connection)
73
+ @spatial = Spatial.new(@connection)
72
74
  end
73
75
 
74
76
  # meta-data
@@ -452,7 +454,53 @@ module Neography
452
454
  def batch_not_streaming(*args)
453
455
  @batch.not_streaming(*args)
454
456
  end
457
+
458
+ # spatial
459
+
460
+ def get_spatial
461
+ @spatial.index
462
+ end
463
+
464
+ def add_point_layer(layer, lat = nil, lon = nil)
465
+ @spatial.add_point_layer(layer, lat, lon)
466
+ end
467
+
468
+ def add_editable_layer(layer, format, node_property_name)
469
+ @spatial.add_editable_layer(layer, format, node_property_name)
470
+ end
471
+
472
+ def get_layer(layer)
473
+ @spatial.get_layer(layer)
474
+ end
455
475
 
476
+ def add_geometry_to_layer(layer, geometry)
477
+ @spatial.add_geometry_to_layer(layer, geometry)
478
+ end
479
+
480
+ def edit_geometry_from_layer(layer, geometry, node)
481
+ @spatial.edit_geometry_from_layer(layer, geometry, node)
482
+ end
483
+
484
+ def add_node_to_layer(layer, node)
485
+ @spatial.add_node_to_layer(layer, node)
486
+ end
487
+
488
+ def find_geometries_in_bbox(layer, minx, maxx, miny, maxy)
489
+ @spatial.find_geometries_in_bbox(layer, minx, maxx, miny, maxy)
490
+ end
491
+
492
+ def find_geometries_within_distance(layer, pointx, pointy, distance)
493
+ @spatial.find_geometries_within_distance(layer, pointx, pointy, distance)
494
+ end
495
+
496
+ def create_spatial_index(name, type = nil, lat = nil, lon = nil)
497
+ @spatial.create_spatial_index(name, type, lat, lon)
498
+ end
499
+
500
+ def add_node_to_spatial_index(index, id)
501
+ @spatial.add_node_to_spatial_index(index, id)
502
+ end
503
+
456
504
  # clean database
457
505
 
458
506
  # For testing (use a separate neo4j instance)
@@ -0,0 +1,154 @@
1
+ module Neography
2
+ class Rest
3
+ class Spatial
4
+ extend Neography::Rest::Paths
5
+ include Neography::Rest::Helpers
6
+
7
+ add_path :index, "/ext/SpatialPlugin"
8
+ add_path :add_simple_point_layer, "/ext/SpatialPlugin/graphdb/addSimplePointLayer"
9
+ add_path :add_editable_layer, "/ext/SpatialPlugin/graphdb/addEditableLayer"
10
+ add_path :get_layer, "/ext/SpatialPlugin/graphdb/getLayer"
11
+ add_path :add_geometry_to_layer, "/ext/SpatialPlugin/graphdb/addGeometryWKTToLayer"
12
+ add_path :edit_geometry_from_layer, "/ext/SpatialPlugin/graphdb/updateGeometryFromWKT"
13
+ add_path :add_node_to_layer, "/ext/SpatialPlugin/graphdb/addNodeToLayer"
14
+ add_path :find_geometries_in_bbox, "/ext/SpatialPlugin/graphdb/findGeometriesInBBox"
15
+ add_path :find_geometries_within_distance,"/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance"
16
+ add_path :create_index, "/index/node"
17
+ add_path :add_to_index, "/index/node/:index"
18
+
19
+ def initialize(connection)
20
+ @connection = connection
21
+ end
22
+
23
+ def index
24
+ @connection.get(index_path)
25
+ end
26
+
27
+ def add_point_layer(layer, lat, lon)
28
+ options = {
29
+ :body => {
30
+ :layer => layer,
31
+ :lat => lat || "lat",
32
+ :lon => lon || "lon"
33
+ }.to_json,
34
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
35
+ }
36
+
37
+ @connection.post(add_simple_point_layer_path, options)
38
+ end
39
+
40
+ def add_editable_layer(layer, format = "WKT", node_property_name = "wkt")
41
+ options = {
42
+ :body => {
43
+ :layer => layer,
44
+ :format => format,
45
+ :nodePropertyName => node_property_name
46
+ }.to_json,
47
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
48
+ }
49
+
50
+ @connection.post(add_editable_layer_path, options)
51
+ end
52
+
53
+ def get_layer(layer)
54
+ options = {
55
+ :body => {
56
+ :layer => layer
57
+ }.to_json,
58
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
59
+ }
60
+ @connection.post(get_layer_path, options)
61
+ end
62
+
63
+ def add_geometry_to_layer(layer, geometry)
64
+ options = {
65
+ :body => {
66
+ :layer => layer,
67
+ :geometry => geometry
68
+ }.to_json,
69
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
70
+ }
71
+ @connection.post(add_geometry_to_layer_path, options)
72
+ end
73
+
74
+ def edit_geometry_from_layer(layer, geometry, node)
75
+ options = {
76
+ :body => {
77
+ :layer => layer,
78
+ :geometry => geometry,
79
+ :geometryNodeId => get_id(node)
80
+ }.to_json,
81
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
82
+ }
83
+ @connection.post(edit_geometry_from_layer_path, options)
84
+ end
85
+
86
+ def add_node_to_layer(layer, node)
87
+ options = {
88
+ :body => {
89
+ :layer => layer,
90
+ :node => get_id(node)
91
+ }.to_json,
92
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
93
+ }
94
+ @connection.post(add_node_to_layer_path, options)
95
+ end
96
+
97
+ def find_geometries_in_bbox(layer, minx, maxx, miny, maxy)
98
+ options = {
99
+ :body => {
100
+ :layer => layer,
101
+ :minx => minx,
102
+ :maxx => maxx,
103
+ :miny => miny,
104
+ :maxy => maxy
105
+ }.to_json,
106
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
107
+ }
108
+ @connection.post(find_geometries_in_bbox_path, options)
109
+ end
110
+
111
+ def find_geometries_within_distance(layer, pointx, pointy, distance)
112
+ options = {
113
+ :body => {
114
+ :layer => layer,
115
+ :pointX => pointx,
116
+ :pointY => pointy,
117
+ :distanceInKm => distance
118
+ }.to_json,
119
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
120
+ }
121
+ @connection.post(find_geometries_within_distance_path, options)
122
+ end
123
+
124
+ def create_spatial_index(name, type, lat, lon)
125
+ options = {
126
+ :body => {
127
+ :name => name,
128
+ :config => {
129
+ :provider => "spatial",
130
+ :geometry_type => type || "point",
131
+ :lat => lat || "lat",
132
+ :lon => lon || "lon"
133
+ }
134
+ }.to_json,
135
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
136
+ }
137
+ @connection.post(create_index_path, options)
138
+ end
139
+
140
+ def add_node_to_spatial_index(index, id)
141
+ options = {
142
+ :body => {
143
+ :uri => @connection.configuration + "/node/#{get_id(id)}",
144
+ :key => "k",
145
+ :value => "v"
146
+ }.to_json,
147
+ :headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
148
+ }
149
+ @connection.post(add_to_index_path(:index => index), options)
150
+ end
151
+
152
+ end
153
+ end
154
+ end
@@ -155,4 +155,51 @@ namespace :neo4j do
155
155
  end
156
156
  end
157
157
 
158
+ task :get_spatial, :version do |t, args|
159
+ args.with_defaults(:version => "2.0.0")
160
+ puts "Installing Neo4j-Spatial #{args[:version]}"
161
+
162
+ unless File.exist?('neo4j-spatial.zip')
163
+ df = File.open('neo4j-spatial.zip', 'wb')
164
+ case args[:version]
165
+ when "2.0.0"
166
+ dist = "dist.neo4j.org"
167
+ request = "/spatial/neo4j-spatial-0.12-neo4j-2.0.0-server-plugin.zip"
168
+ when "1.9"
169
+ dist = "dist.neo4j.org.s3.amazonaws.com"
170
+ request = "/spatial/neo4j-spatial-0.11-neo4j-1.9-server-plugin.zip"
171
+ when "1.8.2"
172
+ dist = "dist.neo4j.org.s3.amazonaws.com"
173
+ request = "/spatial/neo4j-spatial-0.9.1-neo4j-1.8.2-server-plugin.zip"
174
+ else
175
+ abort("I don't know that version of the neo4j spatial plugin")
176
+ end
177
+
178
+ begin
179
+ Net::HTTP.start(dist) do |http|
180
+ http.request_get(request) do |resp|
181
+ resp.read_body do |segment|
182
+ df.write(segment)
183
+ end
184
+ end
185
+ end
186
+ ensure
187
+ df.close()
188
+ end
189
+ end
190
+
191
+ # Extract to neo4j plugins directory
192
+ Zip::File.open('neo4j-spatial.zip') do |zip_file|
193
+ zip_file.each do |f|
194
+ f_path=File.join("neo4j/plugins/", f.name)
195
+ FileUtils.mkdir_p(File.dirname(f_path))
196
+ begin
197
+ zip_file.extract(f, f_path) unless File.exist?(f_path)
198
+ rescue
199
+ puts f.name + " failed to extract."
200
+ end
201
+ end
202
+ end
203
+
204
+ end
158
205
  end
@@ -1,3 +1,3 @@
1
1
  module Neography
2
- VERSION = "1.3.6"
2
+ VERSION = "1.3.7"
3
3
  end
@@ -0,0 +1,166 @@
1
+ require 'spec_helper'
2
+
3
+ describe Neography::Rest do
4
+ before(:each) do
5
+ @neo = Neography::Rest.new
6
+ end
7
+
8
+ describe "find the spatial plugin" do
9
+ it "can get a description of the spatial plugin" do
10
+ si = @neo.get_spatial
11
+ si.should_not be_nil
12
+ si["graphdb"]["addEditableLayer"].should_not be_nil
13
+ end
14
+ end
15
+
16
+ describe "add a point layer" do
17
+ it "can add a simple point layer" do
18
+ pl = @neo.add_point_layer("restaurants")
19
+ pl.should_not be_nil
20
+ pl.first["data"]["layer"].should == "restaurants"
21
+ pl.first["data"]["geomencoder_config"].should == "lon:lat"
22
+ end
23
+
24
+ it "can add a simple point layer with lat and long" do
25
+ pl = @neo.add_point_layer("coffee_shops", "latitude", "longitude")
26
+ pl.should_not be_nil
27
+ pl.first["data"]["layer"].should == "coffee_shops"
28
+ pl.first["data"]["geomencoder_config"].should == "longitude:latitude"
29
+ end
30
+ end
31
+
32
+ describe "add an editable layer" do
33
+ it "can add an editable layer" do
34
+ el = @neo.add_editable_layer("zipcodes", "WKT", "wkt")
35
+ el.should_not be_nil
36
+ el.first["data"]["layer"].should == "zipcodes"
37
+ el.first["data"]["geomencoder_config"].should == "wkt"
38
+ end
39
+ end
40
+
41
+ describe "get a spatial layer" do
42
+ it "can get a layer" do
43
+ sl = @neo.get_layer("restaurants")
44
+ sl.should_not be_nil
45
+ sl.first["data"]["layer"].should == "restaurants"
46
+ end
47
+ end
48
+
49
+ describe "create a spatial index" do
50
+ it "can create a spatial index" do
51
+ index = @neo.create_spatial_index("restaurants")
52
+ index["provider"].should == "spatial"
53
+ index["geometry_type"].should == "point"
54
+ index["lat"].should == "lat"
55
+ index["lon"].should == "lon"
56
+ end
57
+ end
58
+
59
+ describe "add geometry to spatial layer" do
60
+ it "can add a geometry" do
61
+ geometry = "LINESTRING (15.2 60.1, 15.3 60.1)"
62
+ geo = @neo.add_geometry_to_layer("zipcodes", geometry)
63
+ geo.should_not be_nil
64
+ geo.first["data"]["wkt"].should == geometry
65
+ end
66
+ end
67
+
68
+ describe "update geometry from spatial layer" do
69
+ it "can update a geometry" do
70
+ geometry = "LINESTRING (15.2 60.1, 15.3 60.1)"
71
+ geo = @neo.add_geometry_to_layer("zipcodes", geometry)
72
+ geo.should_not be_nil
73
+ geo.first["data"]["wkt"].should == geometry
74
+ geometry = "LINESTRING (14.7 60.1, 15.3 60.1)"
75
+ existing_geo = @neo.edit_geometry_from_layer("zipcodes", geometry, geo)
76
+ existing_geo.first["data"]["wkt"].should == geometry
77
+ existing_geo.first["self"].split('/').last.to_i.should == geo.first["self"].split('/').last.to_i
78
+ end
79
+ end
80
+
81
+ describe "add a node to a layer" do
82
+ it "can add a node to a simple point layer" do
83
+ properties = {:name => "Max's Restaurant", :lat => 41.8819, :lon => 87.6278}
84
+ node = @neo.create_node(properties)
85
+ node.should_not be_nil
86
+ added = @neo.add_node_to_layer("restaurants", node)
87
+ added.first["data"]["lat"].should == properties[:lat]
88
+ added.first["data"]["lon"].should == properties[:lon]
89
+
90
+ added = @neo.add_node_to_index("restaurants", "dummy", "dummy", node)
91
+ added["data"]["lat"].should == properties[:lat]
92
+ added["data"]["lon"].should == properties[:lon]
93
+ end
94
+ end
95
+
96
+ describe "find geometries in a bounding box" do
97
+ it "can find a geometry in a bounding box" do
98
+ properties = {:name => "Max's Restaurant", :lat => 41.8819, :lon => 87.6278}
99
+ node = @neo.find_geometries_in_bbox("restaurants", 87.5, 87.7, 41.7, 41.9)
100
+ node.should_not be_empty
101
+ node.first["data"]["lat"].should == properties[:lat]
102
+ node.first["data"]["lon"].should == properties[:lon]
103
+ node.first["data"]["name"].should == "Max's Restaurant"
104
+ end
105
+
106
+ it "can find a geometry in a bounding box using cypher" do
107
+ properties = {:lat => 60.1, :lon => 15.2}
108
+ @neo.create_spatial_index("geombbcypher", "point", "lat", "lon")
109
+ node = @neo.create_node(properties)
110
+ added = @neo.add_node_to_index("geombbcypher", "dummy", "dummy", node)
111
+ existing_node = @neo.execute_query("start node = node:geombbcypher('bbox:[15.0,15.3,60.0,60.2]') return node")
112
+ existing_node.should_not be_empty
113
+ existing_node["data"][0][0]["data"]["lat"].should == properties[:lat]
114
+ existing_node["data"][0][0]["data"]["lon"].should == properties[:lon]
115
+ end
116
+
117
+ it "can find a geometry in a bounding box using cypher two" do
118
+ properties = {:lat => 60.1, :lon => 15.2}
119
+ @neo.create_spatial_index("geombbcypher2", "point", "lat", "lon")
120
+ node = @neo.create_node(properties)
121
+ added = @neo.add_node_to_spatial_index("geombbcypher2", node)
122
+ existing_node = @neo.execute_query("start node = node:geombbcypher2('bbox:[15.0,15.3,60.0,60.2]') return node")
123
+ existing_node.should_not be_empty
124
+ existing_node["data"][0][0]["data"]["lat"].should == properties[:lat]
125
+ existing_node["data"][0][0]["data"]["lon"].should == properties[:lon]
126
+ end
127
+
128
+ end
129
+
130
+ describe "find geometries within distance" do
131
+ it "can find a geometry within distance" do
132
+ properties = {:name => "Max's Restaurant", :lat => 41.8819, :lon => 87.6278}
133
+ node = @neo.find_geometries_within_distance("restaurants", 87.627, 41.881, 10)
134
+ node.should_not be_empty
135
+ node.first["data"]["lat"].should == properties[:lat]
136
+ node.first["data"]["lon"].should == properties[:lon]
137
+ node.first["data"]["name"].should == "Max's Restaurant"
138
+ end
139
+
140
+ it "can find a geometry within distance using cypher" do
141
+ properties = {:lat => 60.1, :lon => 15.2}
142
+ @neo.create_spatial_index("geowdcypher", "point", "lat", "lon")
143
+ node = @neo.create_node(properties)
144
+ added = @neo.add_node_to_index("geowdcypher", "dummy", "dummy", node)
145
+ existing_node = @neo.execute_query("start n = node:geowdcypher({bbox}) return n", {:bbox => "withinDistance:[60.0,15.0,100.0]"})
146
+ existing_node.should_not be_empty
147
+ existing_node.should_not be_empty
148
+ existing_node["data"][0][0]["data"]["lat"].should == properties[:lat]
149
+ existing_node["data"][0][0]["data"]["lon"].should == properties[:lon]
150
+ end
151
+
152
+ it "can find a geometry within distance using cypher 2" do
153
+ properties = {:lat => 60.1, :lon => 15.2}
154
+ @neo.create_spatial_index("geowdcypher2", "point", "lat", "lon")
155
+ node = @neo.create_node(properties)
156
+ added = @neo.add_node_to_spatial_index("geowdcypher2", node)
157
+ existing_node = @neo.execute_query("start n = node:geowdcypher2({bbox}) return n", {:bbox => "withinDistance:[60.0,15.0,100.0]"})
158
+ existing_node.should_not be_empty
159
+ existing_node.should_not be_empty
160
+ existing_node["data"][0][0]["data"]["lat"].should == properties[:lat]
161
+ existing_node["data"][0][0]["data"]["lon"].should == properties[:lon]
162
+ end
163
+
164
+ end
165
+
166
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neography
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.6
4
+ version: 1.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max De Marzi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-23 00:00:00.000000000 Z
11
+ date: 2014-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -202,6 +202,7 @@ files:
202
202
  - lib/neography/rest/relationship_types.rb
203
203
  - lib/neography/rest/relationships.rb
204
204
  - lib/neography/rest/schema_indexes.rb
205
+ - lib/neography/rest/spatial.rb
205
206
  - lib/neography/rest/transactions.rb
206
207
  - lib/neography/tasks.rb
207
208
  - lib/neography/version.rb
@@ -231,6 +232,7 @@ files:
231
232
  - spec/integration/rest_relationship_spec.rb
232
233
  - spec/integration/rest_relationship_types_spec.rb
233
234
  - spec/integration/rest_schema_index_spec.rb
235
+ - spec/integration/rest_spatial_spec.rb
234
236
  - spec/integration/rest_transaction_spec.rb
235
237
  - spec/integration/rest_traverse_spec.rb
236
238
  - spec/matchers.rb
@@ -312,6 +314,7 @@ test_files:
312
314
  - spec/integration/rest_relationship_spec.rb
313
315
  - spec/integration/rest_relationship_types_spec.rb
314
316
  - spec/integration/rest_schema_index_spec.rb
317
+ - spec/integration/rest_spatial_spec.rb
315
318
  - spec/integration/rest_transaction_spec.rb
316
319
  - spec/integration/rest_traverse_spec.rb
317
320
  - spec/matchers.rb