neography-ajaycb 0.0.21
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.
- data/.gitignore +5 -0
- data/.project +12 -0
- data/.travis.yml +1 -0
- data/CONTRIBUTORS +12 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +39 -0
- data/LICENSE +19 -0
- data/README.rdoc +350 -0
- data/Rakefile +15 -0
- data/examples/facebook.rb +40 -0
- data/examples/facebook_v2.rb +25 -0
- data/examples/greatest.rb +43 -0
- data/examples/linkedin.rb +39 -0
- data/examples/linkedin_v2.rb +22 -0
- data/examples/traversal_example1.rb +65 -0
- data/examples/traversal_example2.rb +54 -0
- data/lib/neography.rb +46 -0
- data/lib/neography/config.rb +17 -0
- data/lib/neography/equal.rb +21 -0
- data/lib/neography/index.rb +13 -0
- data/lib/neography/neography.rb +10 -0
- data/lib/neography/node.rb +45 -0
- data/lib/neography/node_path.rb +29 -0
- data/lib/neography/node_relationship.rb +35 -0
- data/lib/neography/node_traverser.rb +142 -0
- data/lib/neography/path_traverser.rb +94 -0
- data/lib/neography/property.rb +53 -0
- data/lib/neography/property_container.rb +17 -0
- data/lib/neography/railtie.rb +8 -0
- data/lib/neography/relationship.rb +68 -0
- data/lib/neography/relationship_traverser.rb +80 -0
- data/lib/neography/rest.rb +534 -0
- data/lib/neography/tasks.rb +131 -0
- data/lib/neography/version.rb +3 -0
- data/neography.gemspec +29 -0
- data/spec/integration/authorization_spec.rb +48 -0
- data/spec/integration/index_spec.rb +32 -0
- data/spec/integration/neography_spec.rb +10 -0
- data/spec/integration/node_path_spec.rb +222 -0
- data/spec/integration/node_relationship_spec.rb +374 -0
- data/spec/integration/node_spec.rb +215 -0
- data/spec/integration/relationship_spec.rb +37 -0
- data/spec/integration/rest_batch_spec.rb +221 -0
- data/spec/integration/rest_bulk_spec.rb +106 -0
- data/spec/integration/rest_experimental_spec.rb +22 -0
- data/spec/integration/rest_gremlin_fail_spec.rb +46 -0
- data/spec/integration/rest_index_spec.rb +297 -0
- data/spec/integration/rest_node_spec.rb +232 -0
- data/spec/integration/rest_path_spec.rb +209 -0
- data/spec/integration/rest_plugin_spec.rb +67 -0
- data/spec/integration/rest_relationship_spec.rb +327 -0
- data/spec/integration/rest_traverse_spec.rb +149 -0
- data/spec/spec_helper.rb +18 -0
- metadata +222 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
module Neography
|
2
|
+
module NodePath
|
3
|
+
|
4
|
+
def all_paths_to(to)
|
5
|
+
PathTraverser.new(self, to, "allPaths", true)
|
6
|
+
end
|
7
|
+
|
8
|
+
def all_simple_paths_to(to)
|
9
|
+
PathTraverser.new(self, to, "allSimplePaths", true)
|
10
|
+
end
|
11
|
+
|
12
|
+
def all_shortest_paths_to(to)
|
13
|
+
PathTraverser.new(self, to, "shortestPath", true)
|
14
|
+
end
|
15
|
+
|
16
|
+
def path_to(to)
|
17
|
+
PathTraverser.new(self, to, "allPaths", false)
|
18
|
+
end
|
19
|
+
|
20
|
+
def simple_path_to(to)
|
21
|
+
PathTraverser.new(self, to, "allSimplePaths", false)
|
22
|
+
end
|
23
|
+
|
24
|
+
def shortest_path_to(to)
|
25
|
+
PathTraverser.new(self, to, "shortestPath", false)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Neography
|
2
|
+
module NodeRelationship
|
3
|
+
|
4
|
+
def outgoing(types=nil)
|
5
|
+
NodeTraverser.new(self).outgoing(types)
|
6
|
+
end
|
7
|
+
|
8
|
+
def incoming(types=nil)
|
9
|
+
NodeTraverser.new(self).incoming(types)
|
10
|
+
end
|
11
|
+
|
12
|
+
def both(types=nil)
|
13
|
+
NodeTraverser.new(self).both(types)
|
14
|
+
end
|
15
|
+
|
16
|
+
def rels(*types)
|
17
|
+
Neography::RelationshipTraverser.new(self, types, :both)
|
18
|
+
end
|
19
|
+
|
20
|
+
def rel(dir, type)
|
21
|
+
rel = Neography::RelationshipTraverser.new(self, type, dir)
|
22
|
+
rel = rel.first unless rel.nil?
|
23
|
+
rel
|
24
|
+
end
|
25
|
+
|
26
|
+
def rel?(dir=nil, type=nil)
|
27
|
+
if DIRECTIONS.include?(dir.to_s)
|
28
|
+
!self.neo_server.get_node_relationships(self, dir, type).nil?
|
29
|
+
else
|
30
|
+
!self.neo_server.get_node_relationships(self, type, dir).nil?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Neography
|
2
|
+
class NodeTraverser
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_accessor :order, :uniqueness, :depth, :prune, :filter, :relationships
|
6
|
+
|
7
|
+
def initialize(from, types = nil, dir = "all" )
|
8
|
+
@from = from
|
9
|
+
@order = "depth first"
|
10
|
+
@uniqueness = "none"
|
11
|
+
@relationships = Array.new
|
12
|
+
types.each do |type|
|
13
|
+
@relationships << {"type" => type.to_s, "direction" => dir.to_s }
|
14
|
+
end unless types.nil?
|
15
|
+
end
|
16
|
+
|
17
|
+
def <<(other_node)
|
18
|
+
create(other_node)
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def create(other_node)
|
23
|
+
case @relationships.first["direction"]
|
24
|
+
when "outgoing", "out"
|
25
|
+
rel = Neography::Relationship.new(@from.neo_server.create_relationship(@relationships.first["type"], @from, other_node))
|
26
|
+
when "incoming", "in"
|
27
|
+
rel = Neography::Relationship.new(@from.neo_server.create_relationship(@relationships.first["type"], other_node, @from))
|
28
|
+
else
|
29
|
+
rel = Array.new
|
30
|
+
rel << Neography::Relationship.new(@from.neo_server.create_relationship(@relationships.first["type"], @from, other_node))
|
31
|
+
rel << Neography::Relationship.new(@from.neo_server.create_relationship(@relationships.first["type"], other_node, @from))
|
32
|
+
end
|
33
|
+
rel
|
34
|
+
end
|
35
|
+
|
36
|
+
def both(type)
|
37
|
+
@relationships << {"type" => type.to_s, "direction" => "all"}
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def outgoing(type)
|
42
|
+
@relationships << {"type" => type.to_s, "direction" => "out"}
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def incoming(type)
|
47
|
+
@relationships << {"type" => type.to_s, "direction" => "in"}
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def uniqueness(u)
|
52
|
+
@uniqueness = u
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def order(o)
|
57
|
+
@order = o
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def filter(body)
|
62
|
+
@filter = Hash.new
|
63
|
+
@filter["language"] = "javascript"
|
64
|
+
@filter["body"] = body
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def prune(body)
|
69
|
+
@prune = Hash.new
|
70
|
+
@prune["language"] = "javascript"
|
71
|
+
@prune["body"] = body
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def depth(d)
|
76
|
+
d = 2147483647 if d == :all
|
77
|
+
@depth = d
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
def include_start_node
|
82
|
+
@filter = Hash.new
|
83
|
+
@filter["language"] = "builtin"
|
84
|
+
@filter["name"] = "all"
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
def size
|
89
|
+
[*self].size
|
90
|
+
end
|
91
|
+
|
92
|
+
alias_method :length, :size
|
93
|
+
|
94
|
+
def [](index)
|
95
|
+
each_with_index {|node,i| break node if index == i}
|
96
|
+
end
|
97
|
+
|
98
|
+
def empty?
|
99
|
+
first == nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def each
|
103
|
+
iterator.each do |i|
|
104
|
+
node = @from.class.new(i)
|
105
|
+
node.neo_server = @from.neo_server
|
106
|
+
yield node
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def iterator
|
111
|
+
options = Hash.new
|
112
|
+
options["order"] = @order
|
113
|
+
options["uniqueness"] = @uniqueness
|
114
|
+
options["relationships"] = @relationships
|
115
|
+
options["prune evaluator"] = @prune unless @prune.nil?
|
116
|
+
options["return filter"] = @filter unless @filter.nil?
|
117
|
+
options["depth"] = @depth unless @depth.nil?
|
118
|
+
|
119
|
+
if @relationships[0]["type"].empty?
|
120
|
+
rels = @from.neo_server.get_node_relationships(@from, @relationships[0]["direction"])
|
121
|
+
case @relationships[0]["direction"]
|
122
|
+
when "in"
|
123
|
+
rels.collect { |r| @from.neo_server.get_node(r["start"]) } #.uniq
|
124
|
+
when "out"
|
125
|
+
rels.collect { |r| @from.neo_server.get_node(r["end"]) } #.uniq
|
126
|
+
else
|
127
|
+
rels.collect { |r|
|
128
|
+
if @from.neo_id == r["start"].split('/').last
|
129
|
+
@from.neo_server.get_node(r["end"])
|
130
|
+
else
|
131
|
+
@from.neo_server.get_node(r["start"])
|
132
|
+
end
|
133
|
+
} #.uniq
|
134
|
+
end
|
135
|
+
else
|
136
|
+
@from.neo_server.traverse(@from, "nodes", options)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Neography
|
2
|
+
class PathTraverser
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_accessor :depth, :algorithm, :relationships, :get
|
6
|
+
|
7
|
+
def initialize(from, to, algorithm, all=false, types = nil, dir = "all" )
|
8
|
+
@from = from
|
9
|
+
@to = to
|
10
|
+
@algorithm = algorithm
|
11
|
+
@all = all
|
12
|
+
@relationships = Array.new
|
13
|
+
types.each do |type|
|
14
|
+
@relationships << {"type" => type.to_s, "direction" => dir.to_s }
|
15
|
+
end unless types.nil?
|
16
|
+
@get = ["node","rel"]
|
17
|
+
@loaded = Array.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def nodes
|
21
|
+
@get = ["node"]
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def relationships
|
26
|
+
@get = ["rel"]
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
alias_method :rels, :relationships
|
31
|
+
|
32
|
+
def both(type)
|
33
|
+
@relationships << {"type" => type.to_s, "direction" => "all"}
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def outgoing(type)
|
38
|
+
@relationships << {"type" => type.to_s, "direction" => "out"}
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def incoming(type)
|
43
|
+
@relationships << {"type" => type.to_s, "direction" => "in"}
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def depth(d)
|
48
|
+
d = 2147483647 if d == :all
|
49
|
+
@depth = d
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def size
|
54
|
+
[*self].size
|
55
|
+
end
|
56
|
+
|
57
|
+
alias_method :length, :size
|
58
|
+
|
59
|
+
def each
|
60
|
+
iterator.each do |path|
|
61
|
+
paths = Array.new
|
62
|
+
|
63
|
+
if @get.include?("node")
|
64
|
+
path["nodes"].each_with_index do |n, i|
|
65
|
+
@loaded[n.split('/').last.to_i] = Neography::Node.load(n) if @loaded.at(n.split('/').last.to_i).nil?
|
66
|
+
paths[i * 2] = @loaded[n.split('/').last.to_i]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
if @get.include?("rel")
|
71
|
+
path["relationships"].each_with_index do |r, i|
|
72
|
+
@loaded[r.split('/').last.to_i] = Neography::Relationship.load(r) if @loaded.at(r.split('/').last.to_i).nil?
|
73
|
+
paths[i * 2 + 1] = @loaded[r.split('/').last.to_i]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
yield paths.compact
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def empty?
|
82
|
+
first == nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def iterator
|
86
|
+
if @all.nil?
|
87
|
+
@from.neo_server.get_path(@from, @to, @relationships, @depth, @algorithm)
|
88
|
+
else
|
89
|
+
@from.neo_server.get_paths(@from, @to, @relationships, @depth, @algorithm)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Neography
|
2
|
+
module Property
|
3
|
+
|
4
|
+
|
5
|
+
def [](key)
|
6
|
+
return unless respond_to?(key)
|
7
|
+
@table[key]
|
8
|
+
end
|
9
|
+
|
10
|
+
def []=(key, value)
|
11
|
+
k = key.to_s
|
12
|
+
if value.nil?
|
13
|
+
if self.is_a? Neography::Node
|
14
|
+
neo_server.remove_node_properties(self.neo_id, [key])
|
15
|
+
else
|
16
|
+
neo_server.remove_relationship_properties(self.neo_id, [key])
|
17
|
+
end
|
18
|
+
else
|
19
|
+
if self.is_a? Neography::Node
|
20
|
+
neo_server.set_node_properties(self.neo_id, {k => value})
|
21
|
+
else
|
22
|
+
neo_server.set_relationship_properties(self.neo_id, {k => value})
|
23
|
+
end
|
24
|
+
new_ostruct_member(k) unless self.respond_to?(key)
|
25
|
+
end
|
26
|
+
@table[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def new_ostruct_member(name)
|
31
|
+
name = name.to_sym
|
32
|
+
unless self.respond_to?(name)
|
33
|
+
meta = class << self; self; end
|
34
|
+
meta.send(:define_method, name) { @table[name] }
|
35
|
+
meta.send(:define_method, "#{name}=") do |x|
|
36
|
+
@table[name] = x
|
37
|
+
self[name.to_sym] = x
|
38
|
+
end
|
39
|
+
end
|
40
|
+
name
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def self.method_missing(method_sym, *arguments, &block)
|
45
|
+
if (method_sym.to_s =~ /$=/) != nil
|
46
|
+
new_ostruct_member(method_sym.to_s.chomp("="))
|
47
|
+
else
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Neography
|
2
|
+
class PropertyContainer < OpenStruct
|
3
|
+
attr_reader :neo_id
|
4
|
+
|
5
|
+
def initialize(hash=nil)
|
6
|
+
@table = {}
|
7
|
+
if hash
|
8
|
+
@neo_id = hash["self"].split('/').last
|
9
|
+
for k,v in hash["data"]
|
10
|
+
@table[k.to_sym] = v
|
11
|
+
new_ostruct_member(k)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Neography
|
2
|
+
class Relationship < PropertyContainer
|
3
|
+
include Neography::Equal
|
4
|
+
include Neography::Property
|
5
|
+
extend Neography::Index
|
6
|
+
|
7
|
+
attr_accessor :start_node, :end_node, :rel_type
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def create(type, from_node, to_node, props=nil)
|
12
|
+
rel = Neography::Relationship.new(from_node.neo_server.create_relationship(type, from_node, to_node, props))
|
13
|
+
rel.start_node = from_node
|
14
|
+
rel.end_node = to_node
|
15
|
+
rel.rel_type = type
|
16
|
+
rel
|
17
|
+
end
|
18
|
+
|
19
|
+
def load(*args)
|
20
|
+
# the first argument can be an hash of properties to set
|
21
|
+
rel = !args[0].is_a?(Neography::Rest) && args[0] || args[1]
|
22
|
+
|
23
|
+
# a db instance can be given, it is the first argument or the second
|
24
|
+
db = (args[0].is_a?(Neography::Rest) && args[0]) || args[1] || Neography::Rest.new
|
25
|
+
rel = db.get_relationship(rel)
|
26
|
+
unless rel.nil?
|
27
|
+
rel = Neography::Relationship.new(rel)
|
28
|
+
rel.start_node = Neography::Node.load(rel.start_node, db)
|
29
|
+
rel.end_node = Neography::Node.load(rel.end_node, db)
|
30
|
+
end
|
31
|
+
rel
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(hash=nil, server=nil)
|
36
|
+
super(hash)
|
37
|
+
@start_node = hash["start"].split('/').last
|
38
|
+
@end_node = hash["end"].split('/').last
|
39
|
+
@rel_type = hash["type"]
|
40
|
+
neo_server = server
|
41
|
+
end
|
42
|
+
|
43
|
+
def neo_server
|
44
|
+
@neo_server ||= self.start_node.neo_server
|
45
|
+
end
|
46
|
+
|
47
|
+
def neo_server=(server)
|
48
|
+
@neo_server = server
|
49
|
+
end
|
50
|
+
|
51
|
+
def del
|
52
|
+
self.start_node.neo_server.delete_relationship(self.neo_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def exist?
|
56
|
+
!self.start_node.neo_server.get_relationship(self.neo_id).nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
def other_node(node)
|
60
|
+
if node == @start_node
|
61
|
+
@end_node
|
62
|
+
else
|
63
|
+
@start_node
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|