Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 789 lines (492 sloc) 21.333 kB
4ccfae7 @andreasronge try to get a very simple gemspec to work
andreasronge authored
1 = Neo4j
5706e66 added more docs
andreasr authored
2
e477cf3 @andreasronge fixed some lucene bugs, update docs
andreasronge authored
3 Neo4j is a graph database framework for JRuby.
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
4
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
5 It provides:
6 * Mapping of ruby objects to nodes in networks rather than in tables.
7 * Storage of ruby object to a file system.
8 * Fast traversal of relationships between nodes in a hugh node space.
9 * Transaction with rollbacks support.
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
10 * Indexing and querying of ruby objects.
5706e66 added more docs
andreasr authored
11
606c8a4 typo
Peter Neubauer authored
12 Neo4j consists of two modules: Neo4j and Lucene.
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
13 Neo4j depends on the Lucene module.
14
bd948f7 @andreasronge lucene dsl queries can now be used from Neo4j::Node
andreasronge authored
15 It uses two powerful java libraries:
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
16 * Neo4J (http://www.neo4j.org/) - for persistance and traversal of the graph
17 * Lucene (http://lucene.apache.org/java/docs/index.html) for quering and indexing.
5706e66 added more docs
andreasr authored
18
1f7e9fc @andreasronge update README with installation instruction
andreasronge authored
19 == Installation
20
0b28379 @andreasronge released to rubyforge gem repository
andreasronge authored
21 Neo4j exists as a gem at rubyforge
1f7e9fc @andreasronge update README with installation instruction
andreasronge authored
22 To install it please type:
23
0b28379 @andreasronge released to rubyforge gem repository
andreasronge authored
24 gem install neo4j
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
25
715e438 @andreasronge released as 0.0.3. Updated documentation
andreasronge authored
26 To install from the source:
27 * Press the download button at http://github.com/andreasronge/neo4j/tree/master
28 * From command line type: ''rake gem:install''
29
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
30 JRuby version 1.1.4 does not work with Neo4j.rb because of a bug (JRUBY-2959).
31 This bug will be solved in JRuby 1.1.5. JRuby 1.1.3 does work.
32
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
33 == Two Minute Tutorial
9d8ceef more doc fixes
Peter Neubauer authored
34 require "rubygems"
35 require "neo4j"
310e551 @andreasronge Simplified the IMDB example. added transaction around some traversal …
andreasronge authored
36
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
37 class Person
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
38 include Neo4j::NodeMixin
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
39
049f162 @andreasronge replace relations with has and belongs_to, continued to impl. lucene …
andreasronge authored
40 # define Neo4j properties
792bf67 starting to fix the tutorial
Peter Neubauer authored
41 properties :name, :age
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
42
9d8ceef more doc fixes
Peter Neubauer authored
43 # define an one way relationship to any other Person node
44 has_n(:friends).to(Person)
049f162 @andreasronge replace relations with has and belongs_to, continued to impl. lucene …
andreasronge authored
45
b8458eb @andreasronge upgrade to lucene 2.4.0,refactoring and imdb now search using analyze…
andreasronge authored
46 # adds a lucene index on the following properties
47 index :name, :tokenized => true # tokenized means text search, see below
48 index :age # not tokenized means exact search
049f162 @andreasronge replace relations with has and belongs_to, continued to impl. lucene …
andreasronge authored
49 index 'friends.age' # index each friend age as well
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
50 end
51
52 The example above specifies how to map a Neo node to a ruby Person instance.
f12db79 @andreasronge It now runs under JRuby 1.1.5. Started to impl. TOKENIZED lucene fiel…
andreasronge authored
53 Tokenized means that the name will be normalize before its terms will be stored in the index. This is useful for common text where no exact match is needed.
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
54 All neo properties have to be declared (unless you include the DynamicAccessor mixin).
55 Relations between nodes can be specified by using the relations
56
57 Before using neo it has to be started
58
1695b79 @andreasronge updated README.rdoc
andreasronge authored
59 Neo4j.start '/home/neo/neodb', '/home/neo/lucene_index'
60
61 The neo database will be stored at '/home/neo/neodb' and the lucene index files will
62 be stored at '/home/neo/lucene_index'.
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
63
64 Creating a Person node instance
65
66 person = Person.new
67
68 Setting a property:
69
70 person.name = 'kalle'
71 person.age = 23
72
73 If a transaction is not specified then the operation will automatically be wrapped in
74 a transaction.
75
049f162 @andreasronge replace relations with has and belongs_to, continued to impl. lucene …
andreasronge authored
76 Example of quering using lucene:
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
77
049f162 @andreasronge replace relations with has and belongs_to, continued to impl. lucene …
andreasronge authored
78 Person.find (:name => 'kalle')
79 Person.find ('friend.age' => 30) # find people who has a friend of age 30
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
80
6884854 @andreasronge Added support for mapping a ruby class to a neo relationship and sett…
andreasronge authored
81 or DSL, example finding person with name kalle or with age between 20 and 30:
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
82
6884854 @andreasronge Added support for mapping a ruby class to a neo relationship and sett…
andreasronge authored
83 Person.find ((name == 'kalle') | (age == 20..30)) # => [ person ]
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
84
85 Adding a relationship between two nodes:
86
87 person2 = Person.new
88 person.friends << person2
89
90 Traversing relationships
91
92 person.friends.each {|n| ... }
93
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
94 Traversing using a filter
95
96 person.friends{ age == 23 }.each {|n| ...}
97
9f6fdc6 @andreasronge Refactor properties method - split it into two: properties and index.…
andreasronge authored
98 Deleting a relationship
99
100 person.relations[person2].delete
101
102 Deleting a node (and all its relationships)
103
104 person.delete
105
6884854 @andreasronge Added support for mapping a ruby class to a neo relationship and sett…
andreasronge authored
106 Specifying relationships:
2a6f0a9 @andreasronge order rspecs now works. It tests indexing and quering of node relatio…
andreasronge authored
107
cd7889e @andreasronge impl has_n and has_one, see order_spec. Still many broken rspecs
andreasronge authored
108 class Role
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
109 include Neo4j::RelationMixin
cd7889e @andreasronge impl has_n and has_one, see order_spec. Still many broken rspecs
andreasronge authored
110 properties :name
6884854 @andreasronge Added support for mapping a ruby class to a neo relationship and sett…
andreasronge authored
111 end
cd7889e @andreasronge impl has_n and has_one, see order_spec. Still many broken rspecs
andreasronge authored
112
113 class Actor
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
114 include Neo4j::NodeMixin
cd7889e @andreasronge impl has_n and has_one, see order_spec. Still many broken rspecs
andreasronge authored
115 has_n(:acted_in).to(Movie).relation(Role)
6884854 @andreasronge Added support for mapping a ruby class to a neo relationship and sett…
andreasronge authored
116 end
117
cd7889e @andreasronge impl has_n and has_one, see order_spec. Still many broken rspecs
andreasronge authored
118 class Movie
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
119 include Neo4j::NodeMixin
cd7889e @andreasronge impl has_n and has_one, see order_spec. Still many broken rspecs
andreasronge authored
120 properties :title
121 properties :year
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
122
123 # defines a method for traversing incoming acted_in relationships from Actor
124 has_n(:actors).from(Actor, :acted_in)
6884854 @andreasronge Added support for mapping a ruby class to a neo relationship and sett…
andreasronge authored
125 end
126
127
128 Notice that relationships also can have properties.
129 Creating a new Customer Order relationship can be done like this
130
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
131 keanu_reeves = Actor.new
132 matrix = Movie.new
133 keanu_reeves.acted_in << matrix
134
135 or you can also specify this relationship on the incoming node
136
137 keanu_reeves = Actor.new
138 matrix = Movie.new
139 matrix.actors << keanu_reeves
6884854 @andreasronge Added support for mapping a ruby class to a neo relationship and sett…
andreasronge authored
140
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
141 Example of accessing the Role between an Actor and a Movie
6884854 @andreasronge Added support for mapping a ruby class to a neo relationship and sett…
andreasronge authored
142
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
143 keanu_reeves = Actor.new
144 matrix = Movie.new
145 role = keanu_reeves.acted_in.new(matrix)
146 role.name = 'neo'
147
148 or
149 keanu_reeves = Actor.new
150 matrix = Movie.new
151 keanu_reeves.acted_in << matrix
152 keanu_reeves.acted_in
153 keanu_reeves.relations.outgoing(:acted_in)[matrix].name = 'neo'
1f7e9fc @andreasronge update README with installation instruction
andreasronge authored
154
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
155
156 == The Lucene Module
157
4ccfae7 @andreasronge try to get a very simple gemspec to work
andreasronge authored
158 You can use this module without using the Neo4j module.
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
159
160 Example of how to write a document and find it:
f4f5752 @andreasronge updated README.rdoc
andreasronge authored
161 (a document is like a record or row in a relation database).
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
162
163 require 'lucene'
164
165 include Lucene
166
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
167 index = Index.new('var/myindex') # store the index at dir: var/myindex
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
168
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
169 # add one document (a document is like a record or row in a relation database)
170 index << {:id=>'1', :name=>'foo'}
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
171
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
172 # write to the index file
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
173 index.commit
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
174
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
175 # find a document with name foo
176 # hits is a ruby Enumeration of documents
ed872d1 @andreasronge Impl. support for using RAM based lucene index. Refactoring of lucene
andreasronge authored
177 hits = index.find{name == 'foo'}
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
178
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
179 # show the id of the first document (document 0) found
180 # (the document contains all stored fields - see below)
ed872d1 @andreasronge Impl. support for using RAM based lucene index. Refactoring of lucene
andreasronge authored
181 hits[0][:id] # => '1'
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
182
ed872d1 @andreasronge Impl. support for using RAM based lucene index. Refactoring of lucene
andreasronge authored
183 Notice that you have to call the commit method in order to update the index on the disk/RAM.
1c973d9 @andreasronge fixed several bugs regarding the lucene and neo transaction synchroni…
andreasronge authored
184 By performing several update and delete operations before a commit will be much
185 faster then performing commit after each operation.
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
186
3e7df9d @andreasronge added support for indexing several values with the same key. This is …
andreasronge authored
187 === Indexing several values with the same key
188
189 Let say a person can have several phone numbers. How do we index that ?
190
191 index << {:id=>'1', :name=>'adam', :phone => ['987-654', '1234-5678']}
192
193
e477cf3 @andreasronge fixed some lucene bugs, update docs
andreasronge authored
194 === Id field
195
196 All Documents must have one id field. If one is not specified it is :id of type String.
197 A different id can be specified in the second parameter in the Index constructor.
198
199 Index.new('some/path/to/the/index', :my_id)
200
201 To change the type of the my_id from String to a different type see below.
202
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
203 === Conversion of types
204
e477cf3 @andreasronge fixed some lucene bugs, update docs
andreasronge authored
205 Lucene.rb can handle type conversion for you. (The java lucene library stores all
206 the fields as Strings)
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
207 For example if you want the id field to be a fixnum
208
209 require 'lucene'
210 include Lucene
211
212 index = Index.new('var/myindex') # store the index at dir: var/myindex
213 index.field_infos[:id][:type] = Fixnum
214
215 index << {:id=>1, :name=>'foo'} # notice 1 is not a string now
216
217 index.commit
218
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
219 # find that document, hits is a ruby Enumeration of documents
220 hits = index.find(:name => 'foo')
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
221
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
222 # show the id of the first document (document 0) found
223 # (the document contains all stored fields - see below)
224 doc[0][:id] # => 1
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
225
f4f5752 @andreasronge updated README.rdoc
andreasronge authored
226 If the field_info type parameter is not set then it has a default value of String.
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
227
228 === Storage of fields
1695b79 @andreasronge updated README.rdoc
andreasronge authored
229
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
230 By default only the id field will be stored.
231 That means that in the example above the :name field will not be included in the document.
232
233 Example
234 doc = index.find('name' => 'foo')
235 doc[:id] # => 1
236 doc[:name] # => nil
237
238 Use the field info :store=true if you want a field to be stored in the index
239 (otherwise it will only be searchable).
240
241 Example
242
243 require 'lucene'
244 include Lucene
245
246 index = Index.new('var/myindex') # store the index at dir: var/myindex
247 index.field_infos[:id][:type] = Fixnum
248 index.field_infos[:name][:store] = true # store this field
249
250 index << {:id=>1, :name=>'foo'} # notice 1 is not a string now
251
252 index.commit
253
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
254 # find that document, hits is a ruby Enumeration of documents
255 hits = index.find('name' => 'foo')
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
256
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
257 # let say hits only contains one document so we can use doc[0] for that one
258 # that document contains all stored fields (see below)
259 doc[0][:id] # => 1
260 doc[0][:name] # => 'foo'
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
261
f4f5752 @andreasronge updated README.rdoc
andreasronge authored
262 === Setting field infos
263
264 As shown above you can set field infos like this
265
266 index.field_infos[:id][:type] = Fixnum
267
268 Or you can set several properties like this:
269
270 index.field_infos[:id] = {:type => Fixnum, :store => true}
271
272
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
273 === Simple Queries
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
274
275 Lucene.rb support search in several fields:
276 Example
277
278 # finds all document having both name 'foo' and age 42
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
279 hits = index.find('name' => 'foo', :age=>42)
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
280
281 Range queries
282
283 # finds all document having both name 'foo' and age between 3 and 30
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
284 hits = index.find('name' => 'foo', :age=>3..30)
285
286 === Advanced Queries (DSL)
287
288 The queries above can also be written in a lucene.rb DSL:
289
290 hits = index.find { (name == 'andreas') & (foo == 'bar')}
291
5bcdd05 @andreasronge implemented OR DSL queries, example index.find {(name==andreas) | (ag…
andreasronge authored
292 Expression with OR (|) is supported, example
0fd1e72 @andreasronge impl Lucene Query DSL, some simple expression now works, updated RDoc…
andreasronge authored
293
5bcdd05 @andreasronge implemented OR DSL queries, example index.find {(name==andreas) | (ag…
andreasronge authored
294 # find all documents with name 'andreas' or age between 30 and 40
295 hits = index.find { (name == 'andreas') | (age == 30..40)}
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
296
da1a6c9 @andreasronge major refactoring, made Lucene stuff thread safe, I hope
andreasronge authored
297 === Thread-safety
298
299 The Lucene::Index is thread safe.
300 It guarantees that an index is not updated from two thread at the same time.
301
302
303 === Lucene Transactions
304
f4f5752 @andreasronge updated README.rdoc
andreasronge authored
305 Use the Lucene::Transaction in order to do atomic commits.
306 By using a transaction you do not need to call the Index.commit method.
da1a6c9 @andreasronge major refactoring, made Lucene stuff thread safe, I hope
andreasronge authored
307
308 Example:
309
310 Transaction.run do |t|
311 index = Index.new('var/index/foo')
b836b1f @andreasronge fixed some lucene.rb bugs, updated README.rdoc
andreasronge authored
312 index << { id=>42, :name=>'andreas'}
da1a6c9 @andreasronge major refactoring, made Lucene stuff thread safe, I hope
andreasronge authored
313 t.failure # rollback
314 end
315
316 result = index.find('name' => 'andreas')
317 result.size.should == 0
318
4ccfae7 @andreasronge try to get a very simple gemspec to work
andreasronge authored
319 You can find which documents are uncommited by using the uncommited index property.
f4f5752 @andreasronge updated README.rdoc
andreasronge authored
320
4ccfae7 @andreasronge try to get a very simple gemspec to work
andreasronge authored
321 Example
322
323 index = Index.new('var/index/foo')
324 index.uncommited #=> [document1, document2]
325
326 Notice that even if it looks like a new Index instance object was created the index.uncommited
327 may return an not empty array. This is because Index.new is a singleton - a new instance object is not created.
328
79529ee @andreasronge major refactoring of lucene, put it in a new module 'Lucene', added R…
andreasronge authored
329 == The Neo4j Module
330
77981c2 @andreasronge Continue to impl graph DSL (http://gist.github.com/5801). Updated REA…
andreasronge authored
331 === Start and Stop of the Neo Database
332
333 In order to use neo it has to be started first.
334
1695b79 @andreasronge updated README.rdoc
andreasronge authored
335 Neo4j.start '/home/neo/neodb', '/home/neo/lucene_index'
f206a55 @andreasronge refactor the code and api, changed the way to start and stop neo4j. I…
andreasronge authored
336
337 The start method takes 2 paremters - the location on the filesystem of the neo
338 database and the lucene index.
77981c2 @andreasronge Continue to impl graph DSL (http://gist.github.com/5801). Updated REA…
andreasronge authored
339
340 To stop the neo database:
341
f206a55 @andreasronge refactor the code and api, changed the way to start and stop neo4j. I…
andreasronge authored
342 Neo4j.stop
77981c2 @andreasronge Continue to impl graph DSL (http://gist.github.com/5801). Updated REA…
andreasronge authored
343
344
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
345 === Neo4j::NodeMixin
5706e66 added more docs
andreasr authored
346
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
347 Neo4j::NodeMixin is a mixin that lets instances to be stored as a node in the neo node space on disk.
8a0d2d8 better docs
andreasr authored
348 A node can have properties and relationships to other nodes.
349
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
350 Example of how declare a class that has this behaviour:
5706e66 added more docs
andreasr authored
351
cc536ec fixed ugly mixin workaround, more tests, refactoring NodeMixin->Node …
andreasr authored
352 class MyNode
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
353 include Neo4j::NodeMixin
4bf2f46 @andreasronge added some more specs
andreasronge authored
354 end
5706e66 added more docs
andreasr authored
355
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
356
8a0d2d8 better docs
andreasr authored
357 === Create a Node
cc536ec fixed ugly mixin workaround, more tests, refactoring NodeMixin->Node …
andreasr authored
358
359 If a block is provided then the creation of the instance will be performed in an
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
360 transaction, see below for more information on transactions.
cc536ec fixed ugly mixin workaround, more tests, refactoring NodeMixin->Node …
andreasr authored
361
362 node = MyNode.new { }
363
39632b2 @andreasronge implemented delete method on Nodes, updated RDoc
andreasronge authored
364 === Delete a Node
365
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
366 The Neo4j::NodeMixin mixin defines a delete method that will delete the node and all its relationships.
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
367
39632b2 @andreasronge implemented delete method on Nodes, updated RDoc
andreasronge authored
368 Example:
369
370 node = MyNode.new
371 node.delete
372
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
373 The node in the example above will be removed from the neo database on the filesystem and the lucene index
39632b2 @andreasronge implemented delete method on Nodes, updated RDoc
andreasronge authored
374
8a0d2d8 better docs
andreasr authored
375 === Node Properties
cc536ec fixed ugly mixin workaround, more tests, refactoring NodeMixin->Node …
andreasr authored
376
4bf2f46 @andreasronge added some more specs
andreasronge authored
377 In order to use properties they have to be declared first
378
379 class MyNode
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
380 include Neo4j::NodeMixin
4bf2f46 @andreasronge added some more specs
andreasronge authored
381 properties :foo, :bar
382 end
383
384 These properties (foo and bar) will be stored in the Neo database.
385 You can set those properties:
5706e66 added more docs
andreasr authored
386
5fe54df @andreasronge fixed RDoc
andreasronge authored
387 # create a node with two properties in one transaction
cc536ec fixed ugly mixin workaround, more tests, refactoring NodeMixin->Node …
andreasr authored
388 node = MyNode.new { |n|
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
389 n.foo = 123
390 n.bar = 3.14
5706e66 added more docs
andreasr authored
391 }
392
393 # access those properties
394 puts node.foo
395
396
5fe54df @andreasronge fixed RDoc
andreasronge authored
397 You can also set a property like this:
cc536ec fixed ugly mixin workaround, more tests, refactoring NodeMixin->Node …
andreasr authored
398
399 f = SomeNode.new
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
400 f.foo = 123
019f9d0 @andreasronge store Transaction in Thread.current[:transaction], only one transacti…
andreasronge authored
401
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
402 Neo4j.rb supports properties to by of type String, Fixnum, Float and Boolean.
5706e66 added more docs
andreasr authored
403
1695b79 @andreasronge updated README.rdoc
andreasronge authored
404 === Finding all nodes
405
406 To find all nodes of a specific type use the all method.
407 Example
408
409 class Car
410 include Neo4j::Node
411 property :wheels
412 end
413
414 class Volvo < Car
415 end
416
417 v = Volvo.new
418 c = Car.new
419
420 Car.all # will return all relationships from the reference node to car obejcts
421 Volvo.all # will return the same as Car.all
422
423 To return nodes (just like the relations method)
424
425 Car.all.nodes # => [c,v]
426 Volvo.all.nodes # => [c,v]
427
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
428
429 === Relationship has_n
5706e66 added more docs
andreasr authored
430
77981c2 @andreasronge Continue to impl graph DSL (http://gist.github.com/5801). Updated REA…
andreasronge authored
431 Neo relationships are none symmetrical. That means that if A has a relation to B
432 then it may not be true that B has a relation to A.
5706e66 added more docs
andreasr authored
433
39632b2 @andreasronge implemented delete method on Nodes, updated RDoc
andreasronge authored
434 Relationships has to be declared by using the 'relations' class method.
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
435 For example, let say that Person can have a relationship to other nodes with the type 'friends':
5706e66 added more docs
andreasr authored
436
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
437 class Person
cc536ec fixed ugly mixin workaround, more tests, refactoring NodeMixin->Node …
andreasr authored
438 include Neo::Node
715e438 @andreasronge released as 0.0.3. Updated documentation
andreasronge authored
439 has_n :knows # will generate a knows method for outgoing relationships
440 has_n(:known_by).from(:knows) # will generate a known_by method for incomming knows relationship
5706e66 added more docs
andreasr authored
441 end
442
39632b2 @andreasronge implemented delete method on Nodes, updated RDoc
andreasronge authored
443 Example how to add a relation to another node:
5706e66 added more docs
andreasr authored
444
715e438 @andreasronge released as 0.0.3. Updated documentation
andreasronge authored
445 me = Person.new
446 neo = Person.new
447 me.knows << neo # me knows neo but neo does not know me
448
449 Notice that you can also add relationship on the incoming relationship
450 The following example is the same as the example above:
451
452 me = Person.new
453 neo = Person.new
454 neo.known_by << me # neo is known by me, that means that I know neo but neo does have to know me
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
455
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
456 === Relationship has_one
457
458 Example of has_one: A person can have at most one Address
459
460 class Person
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
461 include Neo4j::NodeMixin
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
462 has_one(:address).to(Address)
463 end
464
465 class Address
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
466 include Neo4j::NodeMixin
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
467 properties :city, :road
468 has_n(:people).from(Person, :address)
469 end
470
471 In the example above we have Neo4j.rb will generate the following methods
7a1caf6 @andreasronge using neo-1.0-b7. had to do some minor changes to get all rspecs work…
andreasronge authored
472 * in Person, the method ''address='' and ''address''
473 * in Address, the traversal method ''people'' for traversing incomming relationships from the Person node.
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
474
475 Example of usage
476
477 p = Person.new
478 p.address = Address.new
479 p.address.city = 'malmoe'
480
481
482 Or from the incoming ''address'' relationship
483
484 a = Address.new {|n| n.city = 'malmoe'}
485 a.people << Person.new
486
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
487
5be9ad2 @andreasronge can now set properties on relationships
andreasronge authored
488 === Properties on a relationship
489
490 A relationship can have properties just like a node.
491
492 Example:
493
494 p1 = Person.new
495 p2 = Person.new
496
497 relation = p1.friends.new(p2)
498
499 # set a property 'since' on this relationship bewteen p1 and p2
500 relation.since = 1992
501
cb541b5 @andreasronge Updated README. Traversal and creating relationships now work both fo…
andreasronge authored
502 If a Relationship class has not been specified for a relationship then any properties
503 can be set on the relationship. It has a default relationship class: Neo4j::DynamicRelation
504
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
505 === Traversing relationships:
5706e66 added more docs
andreasr authored
506
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
507 Each type of relationship has a method that returns an Enumerable object that enables you
508 to traverse that type of relationship.
5706e66 added more docs
andreasr authored
509
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
510 For example the Person example above declares one relationship of type friends.
511 You can traverse all Person's friend by doing:
5706e66 added more docs
andreasr authored
512
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
513 f.friends.each { |n| puts n }
5706e66 added more docs
andreasr authored
514
cc30e2a @andreasronge Impl: Fires event when a relationship has been created. Updated READM…
andreasronge authored
515 === Filtering nodes in a relationship
516
517 If you want to find one node in a relationship you can use a filter.
518 Example, let say we want to find a friend with name 'andreas'
5fe54df @andreasronge fixed RDoc
andreasronge authored
519
cc30e2a @andreasronge Impl: Fires event when a relationship has been created. Updated READM…
andreasronge authored
520 n1 = Person.new
521 n2 = Person.new {|n| n.name = 'andreas'}
522 n3 = Person.new
0a52ef1 @andreasronge Updated README
andreasronge authored
523 n1.friends << n2 << n3
cc30e2a @andreasronge Impl: Fires event when a relationship has been created. Updated READM…
andreasronge authored
524 n1.friends{ name == 'andreas' }.to_a # => [n2]
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
525
cc30e2a @andreasronge Impl: Fires event when a relationship has been created. Updated READM…
andreasronge authored
526 The block { name == 'andreas' } will be evaluated on each node in the relationship.
527 If the evaluation returns true the node will be included in the filter search result.
cd1266e @andreasronge update TODO in RSpec README
andreasronge authored
528
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
529 === Finding Relationships
530
531 Given we have the two nodes with a relationship between them:
532
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
533 n1 = Person.new
534 n2 = Person.new
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
535
536 n1.friends << n2
537
538 Then we can find all incoming and outgoing relationships like this:
539
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
540 n1.relations.to_a # => [#<Neo4j::RelationMixin:0x134ae32]
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
541
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
542 A Neo4j::RelationMixin object represents a relationship between two nodes.
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
543
544 n1.relations[0].start_node # => n1
545 n1.relations[0].end_node # => n2
546
547 (TODO relationship can have properties just like a node can)
548
549 === Finding outgoing and incoming relationships
550
551 If we are only interested in all incoming nodes, we can do
552
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
553 n2.relations.incoming # => [#<Neo4j::RelationMixin:0x134ae32]
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
554
5fe54df @andreasronge fixed RDoc
andreasronge authored
555 Or outgoing:
556
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
557 n1.relations.outgoing # => [#<Neo4j::RelationMixin:0x134aea2]
5fe54df @andreasronge fixed RDoc
andreasronge authored
558
baa8394 @andreasronge Added event for when a relationship is deleted, added [] operation on…
andreasronge authored
559 To find a specific relationship use the [] operator:
560
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
561 n1.relations.outgoing[n2] = #<Neo4j::RelationMixin:0x134aea2
baa8394 @andreasronge Added event for when a relationship is deleted, added [] operation on…
andreasronge authored
562
563 Or which is better performance wise (since only friends relationships are being traversed):
564
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
565 n1.relations.outgoing(:friends)[n2] = #<Neo4j::RelationMixin:0x134aea2
baa8394 @andreasronge Added event for when a relationship is deleted, added [] operation on…
andreasronge authored
566
567 === Deleting a relationship
568
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
569 Use the Neo4j::RelationMixin#delete method.
baa8394 @andreasronge Added event for when a relationship is deleted, added [] operation on…
andreasronge authored
570 For example, to delete the relationship between n1 and n2 from the example above:
571
572 n1.relations.outgoing(:friends)[n2].delete
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
573
574 === Finding nodes in a relationship
575
5fe54df @andreasronge fixed RDoc
andreasronge authored
576 If you do not want those relationship object but instead want the nodes you can use the 'nodes' method
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
577 in the Neo4j::RelationMixin object.
5fe54df @andreasronge fixed RDoc
andreasronge authored
578
579 For example:
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
580
581 n2.relations.incoming.nodes # => [n1]
582
77981c2 @andreasronge Continue to impl graph DSL (http://gist.github.com/5801). Updated REA…
andreasronge authored
583 === Finding outgoing/incoming nodes of a specific relationship type
0b0a127 @andreasronge implemented finding incoming/outgoing nodes of a specific type, start…
andreasronge authored
584
585 Let say we want to find who has my phone number and who consider me as a friend
586
587 # who has my phone numbers
77981c2 @andreasronge Continue to impl graph DSL (http://gist.github.com/5801). Updated REA…
andreasronge authored
588 me.relations.incoming(:phone_numbers).nodes # => people with my phone numbers
0b0a127 @andreasronge implemented finding incoming/outgoing nodes of a specific type, start…
andreasronge authored
589
590 # who consider me as a friend
77981c2 @andreasronge Continue to impl graph DSL (http://gist.github.com/5801). Updated REA…
andreasronge authored
591 me.relations.incoming(:friend).nodes # => people with a friend relationship to me
0b0a127 @andreasronge implemented finding incoming/outgoing nodes of a specific type, start…
andreasronge authored
592
593 Remember that relationships are not symmetrical.
5706e66 added more docs
andreasr authored
594
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
595 === Transactions
596
597 All operations that work with the node space (even read operations) must be wrapped in a transaction.
598 Luckly neo4j.rb will automatically create a transaction for those operation that needs it if one is not already provided.
599
600 For example all get, set and find operations will start a new transaction if none is already not runnig (for that thread).
601
21e45e7 @andreasronge Added support for filtering a graph traversal, Example person.friends…
andreasronge authored
602 If you want to perform a set of operation in a single transaction, use the Neo4j::Transaction.run method:
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
603
604 Example
605
ad7f747 @andreasronge removed meta nodes feature, added support for finding incoming/outgoi…
andreasronge authored
606 Neo4j::Transaction.run {
607 node1.foo = "value"
608 node2.bar = "hi"
609 }
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
610
611
612 ==== Rollback
613
614 Neo4j support rollbacks on transaction. Example:
615 Example:
616
617 include 'neo4j'
618
619 node = MyNode.new
620
621 Neo4j::Transaction.run { |t|
622 node.foo = "hej"
623 # something failed so we signal for a failure
624 t.failure # will cause a rollback, node.foo will not be updated
625 }
626
627
628 You can also run it without a block, like this:
629
630 transaction = Neo4j::Transaction.new
631 transaction.start
632 # do something
633 transaction.finish
634
635 === Indexing
636
cba729c @andreasronge Implemented methods for reindex and deleting an lucene index, updated…
andreasronge authored
637 Properties and relationships which should be indexed by lucene can be specified by the index class method.
638 For example to index the proeprties foo and bar
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
639
640 class SomeNode
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
641 include Neo4j::NodeMixin
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
642 properties :foo, :bar
cba729c @andreasronge Implemented methods for reindex and deleting an lucene index, updated…
andreasronge authored
643 index :foo, :bar
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
644 end
645
cba729c @andreasronge Implemented methods for reindex and deleting an lucene index, updated…
andreasronge authored
646 Everytime a node of type SomeNode (or a subclass) is create, deleted or updated the lucene index of will be updated.
647
648 === Deleting or Reindex
649
650 Sometimes it's neccessarly to change the index of a class after alot of node instances already have been created.
651 To delete an index use the class method 'remove_index'
652 To update an index use the class method 'update_index' which will update all already created nodes in the neo database.
653
654 Example
655
656 class Person
657 include Neo4j
658 properties :name, :age, :phone
659 index :name, :age
660 end
661
662 p1 = Person.new {|n| n.name = 'andreas'; n.phone = 123}
663 Person.find (:name => 'andreas') # => [p1]
664 Person.find (:phone => 123) # => []
665
666 # change index and reindex all person nodes already created in the neo database.
667 Person.remove_index :name
668 Person.index :phone # add an index on phone
669 Person.update_index
670
671 Person.find (:name => 'andreas') # => []
672 Person.find (:phone => 123) # => [p1]
3536220 @andreasronge fixed automatically create new transactions when needed, updated RDoc…
andreasronge authored
673
674
b451e4c added find methods an all nodes, using lucene
andreasr authored
675 === Quering (using lucene)
676
4bf2f46 @andreasronge added some more specs
andreasronge authored
677 You can declare properties to be indexed by lucene by the index method:
b451e4c added find methods an all nodes, using lucene
andreasr authored
678
679 Example
680
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
681 class Person
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
682 include Neo4j::NodeMixin
b451e4c added find methods an all nodes, using lucene
andreasr authored
683 properties :name, :age
4bf2f46 @andreasronge added some more specs
andreasronge authored
684 index :name, :age
b451e4c added find methods an all nodes, using lucene
andreasr authored
685 end
686
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
687 node = Person.new
b451e4c added find methods an all nodes, using lucene
andreasr authored
688 node.name = 'foo'
689 node.age = 42
690
691
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
692 Person.find(:name => 'foo', :age => 42) # => [node]
5706e66 added more docs
andreasr authored
693
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
694 The query parameter (like properties on a Neo4j::NodeMixin) can be of type String, Fixnum, Float, boolean or Range.
bd948f7 @andreasronge lucene dsl queries can now be used from Neo4j::Node
andreasronge authored
695 The query above can also be written in a lucene query DSL:
696
697 Person.find{(name =='foo') & (age => 42)} # => [node]
698
699 For more information see the lucene module above.
6887aa3 @andreasronge added documentation
andreasronge authored
700
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
701 === Indexing and Quering Relationships
702
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
703 The Neo4j::NodeMixin#index method can be used to index relationships to other classes.
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
704
705 Example, let say we have to classes, Customer and Orders:
706
707 class Customer
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
708 include Neo4j::NodeMixin
4bf2f46 @andreasronge added some more specs
andreasronge authored
709
710 properties :name
711
712 # specifies outgoing relationships to Order
713 has_n(:orders).to(Order)
714
715 # create an index on customer-->order#total_cost
716 index "orders.total_cost"
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
717 end
718
4bf2f46 @andreasronge added some more specs
andreasronge authored
719
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
720 class Order
4ea2661 @andreasronge moved mixins to lib/neo4j/mixins folder
andreasronge authored
721 include Neo4j::NodeMixin
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
722
4bf2f46 @andreasronge added some more specs
andreasronge authored
723 properties :total_cost
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
724
4bf2f46 @andreasronge added some more specs
andreasronge authored
725 # specifies one incoming relationship from Customer
726 has_one(:customer).from(Customer, :orders)
727
728 # create an index on the order<--customer#name relationship
729 index "customer.name"
730 end
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
731
4bf2f46 @andreasronge added some more specs
andreasronge authored
732 Notice that we can index both incoming and outgoing relationships.
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
733
734 Let's create a customer and one order for that customer
735
736 Neo4j::Transaction.run do
737 cust = Customer.new
738 order = Order.new
739 cust.name = "kalle"
4bf2f46 @andreasronge added some more specs
andreasronge authored
740 order.total_cost = "1000"
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
741
742 cust.orders << order
743 end
744
4bf2f46 @andreasronge added some more specs
andreasronge authored
745 Now we can find both Orders with a total cost between 500 and 2000 and Customers with name 'kalle' using lucene
746
747 Example:
748
749 customers = Customer.find('orders.total_cost' => 500..2000, 'name' => 'kalle')
750
751 Or also possible from the other way:
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
752
4bf2f46 @andreasronge added some more specs
andreasronge authored
753 orders = Order.find('total_cost' => 500..2000, 'customer.name' => 'kalle')
806daa5 @andreasronge Simple indexing and quering of relationships now works. Update README…
andreasronge authored
754
755
c08a13e added docs and more tests
andreasr authored
756 === Unmarshalling
757
758 The neo module will automatically unmarshalling nodes to the correct ruby class.
759 It does this by reading the classname property and loading that ruby class with that node.
760
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
761 class Person
cc536ec fixed ugly mixin workaround, more tests, refactoring NodeMixin->Node …
andreasr authored
762 include Neo::Node
763
c08a13e added docs and more tests
andreasr authored
764 def hello
765 end
766 end
767
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
768 f1 = Person.new {}
c08a13e added docs and more tests
andreasr authored
769
770 # load the class again
f206a55 @andreasronge refactor the code and api, changed the way to start and stop neo4j. I…
andreasronge authored
771 f2 = Neo4j.instance.find_node(foo.neo_node_id)
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
772
773 # f2 will now be new instance of Person, but will be == f1
774 f1 == f2 # => true
cd1266e @andreasronge update TODO in RSpec README
andreasronge authored
775
1695b79 @andreasronge updated README.rdoc
andreasronge authored
776 === Reference node
777
778 There is one node that can always be find - the reference node.
779 Example:
780
781 Neo4j.instance.ref_node
782
783 This node has a relationship to all created nodes.
784 It is used internally to recreate an index or finding all nodes of a specific type.
785
786
7822b8a @andreasronge fixed: delete lucene index when the node is deleted, updated docs and…
andreasronge authored
787
21e45e7 @andreasronge Added support for filtering a graph traversal, Example person.friends…
andreasronge authored
788
Something went wrong with that request. Please try again.