neoid 0.0.51 → 0.1
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/CHANGELOG.md +35 -0
- data/README.md +148 -47
- data/TODO.md +0 -2
- data/lib/neoid.rb +90 -13
- data/lib/neoid/batch.rb +168 -0
- data/lib/neoid/config.rb +6 -0
- data/lib/neoid/middleware.rb +4 -2
- data/lib/neoid/model_additions.rb +60 -15
- data/lib/neoid/model_config.rb +2 -0
- data/lib/neoid/node.rb +103 -54
- data/lib/neoid/relationship.rb +88 -53
- data/lib/neoid/version.rb +1 -1
- data/spec/neoid/batch_spec.rb +170 -0
- data/spec/neoid/config_spec.rb +13 -0
- data/spec/neoid/model_additions_spec.rb +111 -17
- data/spec/neoid/search_spec.rb +0 -1
- data/spec/neoid_spec.rb +7 -1
- data/spec/spec_helper.rb +11 -9
- data/spec/support/models.rb +12 -3
- data/spec/support/schema.rb +4 -0
- metadata +8 -2
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,38 @@
|
|
1
|
+
## v0.1
|
2
|
+
|
3
|
+
* Added batch support, for much faster intiialization of current DB or reindexing all DB.
|
4
|
+
* Dropped indexes per model, instead, using `node_auto_index` and `relationship_auto_index`, letting Neo4j auto index objects.
|
5
|
+
* One `neo_save` method instead of `neo_create` and `neo_update`. It takes care of inserting or updating.
|
6
|
+
|
7
|
+
### Breaking changes:
|
8
|
+
|
9
|
+
Model indexes (such as `users_index`) are now turned off by default. Instead, Neoid uses Neo4j's auto indexing feature.
|
10
|
+
|
11
|
+
In order to have the model indexes back, use this in your configuration:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
Neoid.configure do |c|
|
15
|
+
c.enable_per_model_indexes = true
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
This will turn on for all models.
|
20
|
+
|
21
|
+
You can turn off for a specific model with:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
include Neoid::Node
|
26
|
+
|
27
|
+
neoidable enable_model_index: false do |c|
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
## v0.0.51
|
33
|
+
|
34
|
+
* Releasing Neoid as a gem.
|
35
|
+
|
1
36
|
## v0.0.41
|
2
37
|
|
3
38
|
* fixed really annoying bug caused by Rails design -- Rails doesn't call `after_destroy` when assigning many to many relationships to a model, like `user.movies = [m1, m2, m3]` or `user.update_attributes(params[:user])` where it contains `params[:user][:movie_ids]` list (say from checkboxes), but it DOES CALL after_create for the new relationships. the fix adds after_remove callback to the has_many relationships, ensuring neo4j is up to date with all changes, no matter how they were committed
|
data/README.md
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
[](http://travis-ci.org/elado/neoid)
|
4
4
|
|
5
5
|
|
6
|
-
|
7
6
|
Make your ActiveRecords stored and searchable on Neo4j graph database, in order to make fast graph queries that MySQL would crawl while doing them.
|
8
7
|
|
9
8
|
Neoid to Neo4j is like Sunspot to Solr. You get the benefits of Neo4j speed while keeping your schema on your plain old RDBMS.
|
@@ -12,6 +11,11 @@ Neoid doesn't require JRuby. It's based on the great [Neography](https://github.
|
|
12
11
|
|
13
12
|
Neoid offers querying Neo4j for IDs of objects and then fetch them from your RDBMS, or storing all desired data on Neo4j.
|
14
13
|
|
14
|
+
**Important: Heroku Support is not available because Herokud doesn't support Gremlin. So until further notice, easiest way is to self host a Neo4j on EC2 in the same zone, and connect from your dyno to it**
|
15
|
+
|
16
|
+
## Changelog
|
17
|
+
|
18
|
+
[See Changelog](https://github.com/elado/neoid/blob/master/CHANGELOG.md)
|
15
19
|
|
16
20
|
|
17
21
|
## Installation
|
@@ -19,11 +23,9 @@ Neoid offers querying Neo4j for IDs of objects and then fetch them from your RDB
|
|
19
23
|
Add to your Gemfile and run the `bundle` command to install it.
|
20
24
|
|
21
25
|
```ruby
|
22
|
-
gem 'neoid', '~> 0.
|
26
|
+
gem 'neoid', '~> 0.1'
|
23
27
|
```
|
24
28
|
|
25
|
-
Future versions may have breaking changes but will arrive with migration code.
|
26
|
-
|
27
29
|
**Requires Ruby 1.9.2 or later.**
|
28
30
|
|
29
31
|
## Usage
|
@@ -51,6 +53,11 @@ Neography.configure do |c|
|
|
51
53
|
end
|
52
54
|
|
53
55
|
Neoid.db = $neo
|
56
|
+
|
57
|
+
Neoid.configure do |c|
|
58
|
+
# should Neoid create sub-reference from the ref node (id#0) to every node-model? default: true
|
59
|
+
c.enable_subrefs = true
|
60
|
+
end
|
54
61
|
```
|
55
62
|
|
56
63
|
`01_` in the file name is in order to get this file loaded first, before the models (initializers are loaded alphabetically).
|
@@ -71,9 +78,9 @@ class User < ActiveRecord::Base
|
|
71
78
|
end
|
72
79
|
```
|
73
80
|
|
74
|
-
This will help to create a corresponding node on Neo4j when
|
81
|
+
This will help to create/update/destroy a corresponding node on Neo4j when changed are made a User model.
|
75
82
|
|
76
|
-
Then, you can customize what fields will be saved on the node in Neo4j, inside neoidable configuration:
|
83
|
+
Then, you can customize what fields will be saved on the node in Neo4j, inside `neoidable` configuration, using `field`. You can also pass blocks to save content that's not a real column:
|
77
84
|
|
78
85
|
```ruby
|
79
86
|
class User < ActiveRecord::Base
|
@@ -89,7 +96,6 @@ class User < ActiveRecord::Base
|
|
89
96
|
end
|
90
97
|
```
|
91
98
|
|
92
|
-
|
93
99
|
#### Relationships
|
94
100
|
|
95
101
|
Let's assume that a `User` can `Like` `Movie`s:
|
@@ -151,7 +157,7 @@ class Like < ActiveRecord::Base
|
|
151
157
|
end
|
152
158
|
```
|
153
159
|
|
154
|
-
Neoid adds `neo_node` and `neo_relationships` to nodes and relationships, respectively.
|
160
|
+
Neoid adds the metohds `neo_node` and `neo_relationships` to instances of nodes and relationships, respectively.
|
155
161
|
|
156
162
|
So you could do:
|
157
163
|
|
@@ -169,38 +175,52 @@ rel.end_node # user.movies.first.neo_node
|
|
169
175
|
rel.rel_type # 'likes'
|
170
176
|
```
|
171
177
|
|
172
|
-
|
178
|
+
#### Disabling auto saving to Neo4j:
|
173
179
|
|
174
|
-
|
180
|
+
If you'd like to save nodes manually rather than after_save, use `auto_index: false`:
|
175
181
|
|
176
182
|
```ruby
|
177
|
-
|
178
|
-
|
179
|
-
class Movie < ActiveRecord::Base
|
183
|
+
class User < ActiveRecord::Base
|
180
184
|
include Neoid::Node
|
181
|
-
|
182
|
-
neoidable do |c|
|
183
|
-
c.field :slug
|
184
|
-
c.field :name
|
185
|
-
|
186
|
-
c.search do |s|
|
187
|
-
# full-text index fields
|
188
|
-
s.fulltext :name
|
189
|
-
s.fulltext :description
|
190
|
-
|
191
|
-
# just index for exact matches
|
192
|
-
s.index :year
|
193
|
-
end
|
185
|
+
|
186
|
+
neoidable auto_index: false do |c|
|
194
187
|
end
|
195
188
|
end
|
196
|
-
```
|
197
189
|
|
198
|
-
|
190
|
+
user = User.create!(name: "Elad") # no node is created in Neo4j!
|
191
|
+
|
192
|
+
user.neo_save # now there is!
|
193
|
+
```
|
199
194
|
|
200
195
|
## Querying
|
201
196
|
|
202
197
|
You can query with all [Neography](https://github.com/maxdemarzi/neography)'s API: `traverse`, `execute_query` for Cypher, and `execute_script` for Gremlin.
|
203
198
|
|
199
|
+
### Basics:
|
200
|
+
|
201
|
+
#### Finding a node by ID
|
202
|
+
|
203
|
+
Nodes and relationships are auto indexed in the `node_auto_index` and `relationship_auto_index` indexes, where the key is `Neoid::UNIQUE_ID_KEY` (which is 'neoid_unique_id') and the value is a combination of the class name and model id, `Movie:43`, this value is accessible with `model.neo_unique_id`. So use the constant and this method, never rely on assebling those values on your own because they might change in the future.
|
204
|
+
|
205
|
+
That means, you can query like this:
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
Neoid.db.get_node_auto_index(Neoid::UNIQUE_ID_KEY, user.neo_unique_id)
|
209
|
+
# => returns a Neography hash
|
210
|
+
|
211
|
+
Neoid::Node.from_hash(Neoid.db.get_node_auto_index(Neoid::UNIQUE_ID_KEY, user.neo_unique_id))
|
212
|
+
# => returns a Neography::Node
|
213
|
+
```
|
214
|
+
|
215
|
+
#### Finding all nodes of type
|
216
|
+
|
217
|
+
If Subreferences are enabled, you can get the subref node and then get all attached nodes:
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
Neoid.ref_node.outgoing('users_subref').first.outgoing('users_subref').to_a
|
221
|
+
# => this, according to Neography, returns an array of Neography::Node so no conversion is needed
|
222
|
+
```
|
223
|
+
|
204
224
|
### Gremlin Example:
|
205
225
|
|
206
226
|
These examples query Neo4j using Gremlin for IDs of objects, and then fetches them from ActiveRecord with an `in` query.
|
@@ -208,7 +228,7 @@ These examples query Neo4j using Gremlin for IDs of objects, and then fetches th
|
|
208
228
|
Of course, you can store using the `neoidable do |c| c.field ... end` all the data you need in Neo4j and avoid querying ActiveRecord.
|
209
229
|
|
210
230
|
|
211
|
-
**Most
|
231
|
+
**Most liked movies**
|
212
232
|
|
213
233
|
```ruby
|
214
234
|
gremlin_query = <<-GREMLIN
|
@@ -228,15 +248,18 @@ movie_ids = Neoid.db.execute_script(gremlin_query)
|
|
228
248
|
Movie.where(id: movie_ids)
|
229
249
|
```
|
230
250
|
|
231
|
-
|
251
|
+
*Side note: the resulted movies won't be sorted by like count because the RDBMS won't necessarily do it as we passed a list of IDs. You can sort it yourself with array manipulation, since you have the ids.*
|
252
|
+
|
232
253
|
|
233
254
|
**Movies of user friends that the user doesn't have**
|
234
255
|
|
256
|
+
Let's assume we have another `Friendship` model which is a relationship with start/end nodes of `user` and type of `friends`,
|
257
|
+
|
235
258
|
```ruby
|
236
259
|
user = User.find(1)
|
237
260
|
|
238
261
|
gremlin_query = <<-GREMLIN
|
239
|
-
u = g.idx('
|
262
|
+
u = g.idx('node_auto_index').get(unique_id_key, user_unique_id).next()
|
240
263
|
movies = []
|
241
264
|
|
242
265
|
u
|
@@ -246,15 +269,42 @@ gremlin_query = <<-GREMLIN
|
|
246
269
|
.except(movies).collect{it.ar_id}
|
247
270
|
GREMLIN
|
248
271
|
|
249
|
-
movie_ids = Neoid.db.execute_script(gremlin_query,
|
272
|
+
movie_ids = Neoid.db.execute_script(gremlin_query, unique_id_key: Neoid::UNIQUE_ID_KEY, user_unique_id: user.neo_unique_id)
|
250
273
|
|
251
274
|
Movie.where(id: movie_ids)
|
252
275
|
```
|
253
276
|
|
254
|
-
|
277
|
+
## Full Text Search
|
255
278
|
|
279
|
+
### Index for Full-Text Search
|
256
280
|
|
257
|
-
|
281
|
+
Using `search` block inside a `neoidable` block, you can store certain fields.
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
# movie.rb
|
285
|
+
|
286
|
+
class Movie < ActiveRecord::Base
|
287
|
+
include Neoid::Node
|
288
|
+
|
289
|
+
neoidable do |c|
|
290
|
+
c.field :slug
|
291
|
+
c.field :name
|
292
|
+
|
293
|
+
c.search do |s|
|
294
|
+
# full-text index fields
|
295
|
+
s.fulltext :name
|
296
|
+
s.fulltext :description
|
297
|
+
|
298
|
+
# just index for exact matches
|
299
|
+
s.index :year
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
```
|
304
|
+
|
305
|
+
Records will be automatically indexed when inserted or updated.
|
306
|
+
|
307
|
+
### Querying a Full-Text Search index
|
258
308
|
|
259
309
|
```ruby
|
260
310
|
# will match all movies with full-text match for name/description. returns ActiveRecord instanced
|
@@ -270,14 +320,63 @@ Neoid.neo_search([Movie, User], "hello")
|
|
270
320
|
Movie.neo_search(year: 2013).results
|
271
321
|
```
|
272
322
|
|
323
|
+
Full text search with Neoid is very limited and is likely not to develop more than this basic functionality. I strongly recommend using gems like Sunspot over Solr.
|
324
|
+
|
325
|
+
## Batches
|
326
|
+
|
327
|
+
Neoid has a batch ability, that is good for mass updateing/inserting of nodes/relationships. It sends batched requests to Neography, and takes care of type conversion (neography batch returns hashes and other primitive types) and "after" actions (via promises).
|
328
|
+
|
329
|
+
A few examples, easy to complex:
|
330
|
+
|
331
|
+
```ruby
|
332
|
+
Neoid.batch(batch_size: 100) do
|
333
|
+
User.all.each(&:neo_save)
|
334
|
+
end
|
335
|
+
```
|
336
|
+
With `then`:
|
337
|
+
|
338
|
+
```ruby
|
339
|
+
User.first.name # => "Elad"
|
340
|
+
|
341
|
+
Neoid.batch(batch_size: 100) do
|
342
|
+
User.all.each(&:neo_save)
|
343
|
+
end.then do |results|
|
344
|
+
# results is an array of the script results from neo4j REST.
|
345
|
+
|
346
|
+
results[0].name # => "Elad"
|
347
|
+
end
|
348
|
+
```
|
349
|
+
|
350
|
+
*Nodes and relationships in the results are automatically converted to Neography::Node and Neography::Relationship, respectively.*
|
351
|
+
|
352
|
+
With individual `then` as well as `then` for the entire batch:
|
353
|
+
|
354
|
+
```ruby
|
355
|
+
Neoid.batch(batch_size: 30) do |batch|
|
356
|
+
(1..90).each do |i|
|
357
|
+
(batch << [:create_node, { name: "Hello #{i}" }]).then { |result| puts result.name }
|
358
|
+
end
|
359
|
+
end.then do |results|
|
360
|
+
puts results.collect(&:name)
|
361
|
+
end
|
362
|
+
```
|
363
|
+
|
364
|
+
When in a batch, `neo_save` adds gremlin scripts to a batch, instead of running them immediately. The batch flushes whenever the `batch_size` option is met.
|
365
|
+
So even if you have 20000 users, Neoid will insert/update in smaller batches. Default `batch_size` is 200.
|
366
|
+
|
367
|
+
|
273
368
|
## Inserting records of existing app
|
274
369
|
|
275
|
-
If you have an existing database and just want to integrate Neoid, configure the `neoidable`s and run in a rake task or console
|
370
|
+
If you have an existing database and just want to integrate Neoid, configure the `neoidable`s and run in a rake task or console.
|
371
|
+
|
372
|
+
Use batches! It's free, and much faster. Also, you should use `includes` to incude the relationship edges on relationship entities, so it doesn't query the DB on each relationship.
|
276
373
|
|
277
374
|
```ruby
|
278
|
-
|
375
|
+
Neoid.batch do
|
376
|
+
[ Like.includes(:user).includes(:movie), OtherRelationshipModel.includes(:from_model).includes(:to_model) ].each { |model| model.all.each(&:neo_save) }
|
279
377
|
|
280
|
-
NodeModel.all.each(&:
|
378
|
+
NodeModel.all.each(&:neo_save)
|
379
|
+
end
|
281
380
|
```
|
282
381
|
|
283
382
|
This will loop through all of your relationship records and generate the two edge nodes along with a relationship (eager loading for better performance).
|
@@ -289,30 +388,32 @@ Better interface for that in the future.
|
|
289
388
|
|
290
389
|
## Behind The Scenes
|
291
390
|
|
292
|
-
Whenever the `neo_node` on nodes or `neo_relationship` on relationships is called, Neoid checks if there's a corresponding node/relationship in Neo4j. If not, it does the following:
|
391
|
+
Whenever the `neo_node` on nodes or `neo_relationship` on relationships is called, Neoid checks if there's a corresponding node/relationship in Neo4j (with the auto indexes). If not, it does the following:
|
293
392
|
|
294
393
|
### For Nodes:
|
295
394
|
|
296
|
-
1. Ensures there's a sub reference node (read [here](http://docs.neo4j.org/chunked/stable/tutorials-java-embedded-index.html) about sub
|
395
|
+
1. Ensures there's a sub reference node (read [here](http://docs.neo4j.org/chunked/stable/tutorials-java-embedded-index.html) about sub references), if that option is on.
|
297
396
|
2. Creates a node based on the ActiveRecord, with the `id` attribute and all other attributes from `neoidable`'s field list
|
298
397
|
3. Creates a relationship between the sub reference node and the newly created node
|
299
|
-
4.
|
398
|
+
4. Auto indexes a node in the auto index, for fast lookup in the future
|
300
399
|
|
301
|
-
Then, when it needs to find it again, it just seeks the
|
400
|
+
Then, when it needs to find it again, it just seeks the auto index with that ActiveRecord id.
|
302
401
|
|
303
402
|
### For Relationships:
|
304
403
|
|
305
|
-
Like Nodes, it uses an
|
404
|
+
Like Nodes, it uses an auto index, to look up a relationship by ActiveRecord id
|
306
405
|
|
307
406
|
1. With the options passed in the `neoidable`, it fetches the `start_node` and `end_node`
|
308
407
|
2. Then, it calls `neo_node` on both, in order to create the Neo4j nodes if they're not created yet, and creates the relationship with the type from the options.
|
309
|
-
3.
|
408
|
+
3. Adds the relationship to the relationship index.
|
310
409
|
|
311
410
|
## Testing
|
312
411
|
|
313
412
|
In order to test your app or this gem, you need a running Neo4j database, dedicated to tests.
|
314
413
|
|
315
|
-
I use port 7574 for
|
414
|
+
I use port 7574 for testing.
|
415
|
+
|
416
|
+
To run another database locally (read [here](http://docs.neo4j.org/chunked/1.9.M03/server-installation.html#_multiple_server_instances_on_one_machine) too):
|
316
417
|
|
317
418
|
Copy the entire Neo4j database folder to a different location,
|
318
419
|
|
@@ -344,7 +445,7 @@ end
|
|
344
445
|
|
345
446
|
## Testing This Gem
|
346
447
|
|
347
|
-
|
448
|
+
Run the Neo4j DB on port 7574, and run `rake` from the gem folder.
|
348
449
|
|
349
450
|
## Contributing
|
350
451
|
|
@@ -356,9 +457,9 @@ Please create a [new issue](https://github.com/elado/neoid/issues) if you run in
|
|
356
457
|
Unfortunately, as for now, Neo4j add-on on Heroku doesn't support Gremlin. Therefore, this gem won't work on Heroku's add on. You should self-host a Neo4j instance on an EC2 or any other server.
|
357
458
|
|
358
459
|
|
359
|
-
##
|
460
|
+
## TO DO
|
360
461
|
|
361
|
-
[
|
462
|
+
[TO DO](HTTPS://GITHUB.COM/ELADO/NEOID/BLOB/MASTER/TODO.MD)
|
362
463
|
|
363
464
|
|
364
465
|
---
|
data/TODO.md
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
# Neoid - To Do
|
2
2
|
|
3
|
-
* Allow to disable sub reference nodes through options
|
4
3
|
* Execute queries/scripts from model and not Neography (e.g. `Movie.neo_gremlin(gremlin_query)` with query that outputs IDs, returns a list of `Movie`s)
|
5
4
|
* Rake task to index all nodes and relatiohsips in Neo4j
|
6
|
-
* Test update node
|
data/lib/neoid.rb
CHANGED
@@ -1,24 +1,27 @@
|
|
1
|
+
require 'neography'
|
1
2
|
require 'neoid/version'
|
3
|
+
require 'neoid/config'
|
2
4
|
require 'neoid/model_config'
|
3
5
|
require 'neoid/model_additions'
|
4
6
|
require 'neoid/search_session'
|
5
7
|
require 'neoid/node'
|
6
8
|
require 'neoid/relationship'
|
9
|
+
require 'neoid/batch'
|
7
10
|
require 'neoid/database_cleaner'
|
8
11
|
require 'neoid/railtie' if defined?(Rails)
|
9
12
|
|
10
13
|
module Neoid
|
11
|
-
DEFAULT_FULLTEXT_SEARCH_INDEX_NAME =
|
14
|
+
DEFAULT_FULLTEXT_SEARCH_INDEX_NAME = :neoid_default_search_index
|
15
|
+
NODE_AUTO_INDEX_NAME = 'node_auto_index'
|
16
|
+
RELATIONSHIP_AUTO_INDEX_NAME = 'relationship_auto_index'
|
17
|
+
UNIQUE_ID_KEY = 'neoid_unique_id'
|
12
18
|
|
13
19
|
class << self
|
14
20
|
attr_accessor :db
|
15
21
|
attr_accessor :logger
|
16
22
|
attr_accessor :ref_node
|
17
23
|
attr_accessor :env_loaded
|
18
|
-
|
19
|
-
def models
|
20
|
-
@models ||= []
|
21
|
-
end
|
24
|
+
attr_reader :config
|
22
25
|
|
23
26
|
def node_models
|
24
27
|
@node_models ||= []
|
@@ -29,20 +32,42 @@ module Neoid
|
|
29
32
|
end
|
30
33
|
|
31
34
|
def config
|
32
|
-
@config ||=
|
35
|
+
@config ||= begin
|
36
|
+
c = Neoid::Config.new
|
37
|
+
|
38
|
+
# default
|
39
|
+
c.enable_subrefs = true
|
40
|
+
c.enable_per_model_indexes = false
|
41
|
+
|
42
|
+
c
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def configure
|
47
|
+
yield config
|
33
48
|
end
|
34
49
|
|
35
50
|
def initialize_all
|
36
51
|
@env_loaded = true
|
37
|
-
|
38
|
-
|
39
|
-
|
52
|
+
logger.info "Neoid initialize_all"
|
53
|
+
initialize_relationships
|
54
|
+
initialize_server
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize_server
|
58
|
+
initialize_auto_index
|
59
|
+
initialize_subrefs
|
60
|
+
initialize_per_model_indexes
|
40
61
|
end
|
41
62
|
|
42
63
|
def db
|
43
64
|
raise "Must set Neoid.db with a Neography::Rest instance" unless @db
|
44
65
|
@db
|
45
66
|
end
|
67
|
+
|
68
|
+
def batch(options={}, &block)
|
69
|
+
Neoid::Batch.new(options, &block).run
|
70
|
+
end
|
46
71
|
|
47
72
|
def logger
|
48
73
|
@logger ||= Logger.new(ENV['NEOID_LOG'] ? ENV['NEOID_LOG_FILE'] || $stdout : '/dev/null')
|
@@ -53,10 +78,7 @@ module Neoid
|
|
53
78
|
end
|
54
79
|
|
55
80
|
def reset_cached_variables
|
56
|
-
|
57
|
-
klass.instance_variable_set(:@_neo_subref_node, nil)
|
58
|
-
end
|
59
|
-
$neo_ref_node = nil
|
81
|
+
initialize_subrefs
|
60
82
|
end
|
61
83
|
|
62
84
|
def clean_db(confirm)
|
@@ -83,6 +105,19 @@ module Neoid
|
|
83
105
|
self.enabled = old
|
84
106
|
end
|
85
107
|
|
108
|
+
def execute_script_or_add_to_batch(gremlin_query, script_vars)
|
109
|
+
if Neoid::Batch.current_batch
|
110
|
+
# returns a SingleResultPromiseProxy!
|
111
|
+
Neoid::Batch.current_batch << [:execute_script, gremlin_query, script_vars]
|
112
|
+
else
|
113
|
+
value = Neoid.db.execute_script(gremlin_query, script_vars)
|
114
|
+
|
115
|
+
value = yield(value) if block_given?
|
116
|
+
|
117
|
+
Neoid::BatchPromiseProxy.new(value)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
86
121
|
# create a fulltext index if not exists
|
87
122
|
def ensure_default_fulltext_search_index
|
88
123
|
Neoid.db.create_node_index(DEFAULT_FULLTEXT_SEARCH_INDEX_NAME, 'fulltext', 'lucene') unless (indexes = Neoid.db.list_node_indexes) && indexes[DEFAULT_FULLTEXT_SEARCH_INDEX_NAME]
|
@@ -155,5 +190,47 @@ module Neoid
|
|
155
190
|
|
156
191
|
"(" + term.split(/\s+/).reject(&:empty?).map{ |t| "#{field}#{fulltext}:#{sanitize_term(t)}" }.join(" AND ") + ")"
|
157
192
|
end
|
193
|
+
|
194
|
+
def initialize_relationships
|
195
|
+
logger.info "Neoid initialize_relationships"
|
196
|
+
relationship_models.each do |rel_model|
|
197
|
+
Relationship.initialize_relationship(rel_model)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def initialize_auto_index
|
202
|
+
logger.info "Neoid initialize_auto_index"
|
203
|
+
Neoid.db.set_node_auto_index_status(true)
|
204
|
+
Neoid.db.add_node_auto_index_property(UNIQUE_ID_KEY)
|
205
|
+
|
206
|
+
Neoid.db.set_relationship_auto_index_status(true)
|
207
|
+
Neoid.db.add_relationship_auto_index_property(UNIQUE_ID_KEY)
|
208
|
+
end
|
209
|
+
|
210
|
+
def initialize_subrefs
|
211
|
+
return unless config.enable_subrefs
|
212
|
+
|
213
|
+
node_models.each do |klass|
|
214
|
+
klass.reset_neo_subref_node
|
215
|
+
end
|
216
|
+
|
217
|
+
logger.info "Neoid initialize_subrefs"
|
218
|
+
batch do
|
219
|
+
node_models.each(&:neo_subref_node)
|
220
|
+
end.then do |results|
|
221
|
+
node_models.zip(results).each do |klass, subref|
|
222
|
+
klass.neo_subref_node = subref
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def initialize_per_model_indexes
|
228
|
+
return unless config.enable_per_model_indexes
|
229
|
+
|
230
|
+
logger.info "Neoid initialize_subrefs"
|
231
|
+
batch do
|
232
|
+
node_models.each(&:neo_model_index)
|
233
|
+
end
|
234
|
+
end
|
158
235
|
end
|
159
236
|
end
|