class Neo4j::Migration::AddIdProperty

Attributes

models_filename[R]

Public Class Methods

new(path = default_path) click to toggle source
   # File lib/neo4j/migration.rb
28 def initialize(path = default_path)
29   @models_filename = File.join(joined_path(path), 'add_id_property.yml')
30 end

Public Instance Methods

migrate() click to toggle source
   # File lib/neo4j/migration.rb
32 def migrate
33   models = ActiveSupport::HashWithIndifferentAccess.new(YAML.load_file(models_filename))[:models]
34   output 'This task will add an ID Property every node in the given file.'
35   output 'It may take a significant amount of time, please be patient.'
36   models.each do |model|
37     output
38     output
39     output "Adding IDs to #{model}"
40     add_ids_to model.constantize
41   end
42 end
setup() click to toggle source
   # File lib/neo4j/migration.rb
44       def setup
45         FileUtils.mkdir_p('db/neo4j-migrate')
46 
47         return if File.file?(models_filename)
48 
49         File.open(models_filename, 'w') do |file|
50           message = <<MESSAGE
51 # Provide models to which IDs should be added.
52 # # It will only modify nodes that do not have IDs. There is no danger of overwriting data.
53 # # models: [Student,Lesson,Teacher,Exam]\nmodels: []
54 MESSAGE
55           file.write(message)
56         end
57       end

Private Instance Methods

add_ids_to(model) click to toggle source
   # File lib/neo4j/migration.rb
61 def add_ids_to(model)
62   max_per_batch = (ENV['MAX_PER_BATCH'] || default_max_per_batch).to_i
63 
64   label = model.mapped_label_name
65   last_time_taken = nil
66 
67   until (nodes_left = idless_count(label, model.primary_key)) == 0
68     print_status(last_time_taken, max_per_batch, nodes_left)
69 
70     count = [nodes_left, max_per_batch].min
71     last_time_taken = Benchmark.realtime do
72       max_per_batch = id_batch_set(label, model.primary_key, count.times.map { new_id_for(model) }, count)
73     end
74   end
75 end
default_max_per_batch() click to toggle source
    # File lib/neo4j/migration.rb
114 def default_max_per_batch
115   900
116 end
id_batch_set(label, id_property, new_ids, count) click to toggle source
    # File lib/neo4j/migration.rb
 94 def id_batch_set(label, id_property, new_ids, count)
 95   tx = Neo4j::Transaction.new
 96 
 97   Neo4j::Session.query("MATCH (n:`#{label}`) WHERE NOT EXISTS(n.#{id_property})
 98     with COLLECT(n) as nodes, #{new_ids} as ids
 99     FOREACH(i in range(0,#{count - 1})|
100       FOREACH(node in [nodes[i]]|
101         SET node.#{id_property} = ids[i]))
102     RETURN distinct(true)
103     LIMIT #{count}")
104 
105   count
106 rescue Neo4j::Server::CypherResponse::ResponseError, Faraday::TimeoutError
107   new_max_per_batch = (max_per_batch * 0.8).round
108   output "Error querying #{max_per_batch} nodes.  Trying #{new_max_per_batch}"
109   new_max_per_batch
110 ensure
111   tx.close
112 end
idless_count(label, id_property) click to toggle source
   # File lib/neo4j/migration.rb
77 def idless_count(label, id_property)
78   Neo4j::Session.query.match(n: label).where("NOT EXISTS(n.#{id_property})").pluck('COUNT(n) AS ids').first
79 end
new_id_for(model) click to toggle source
    # File lib/neo4j/migration.rb
118 def new_id_for(model)
119   if model.id_property_info[:type][:auto]
120     SecureRandom.uuid
121   else
122     model.new.send(model.id_property_info[:type][:on])
123   end
124 end
print_status(last_time_taken, max_per_batch, nodes_left) click to toggle source