Class: ActiveGraph::Core::Query
- Inherits:
 - 
      Object
      
        
- Object
 - ActiveGraph::Core::Query
 
 
- Includes:
 - QueryClauses, QueryExt, QueryFindInBatches, Enumerable
 
- Defined in:
 - lib/active_graph/core/query.rb
 
Overview
Allows for generation of cypher queries via ruby method calls (inspired by ActiveRecord / arel syntax)
Can be used to express cypher queries in ruby nicely, or to more easily generate queries programatically.
Also, queries can be passed around an application to progressively build a query across different concerns
See also the following link for full cypher language documentation: docs.neo4j.org/chunked/milestone/cypher-query-lang.html
Defined Under Namespace
Classes: Parameters, PartitionedClauses
Constant Summary collapse
- DEFINED_CLAUSES =
 {}
- METHODS =
          
DETACH DELETE clause
 %w[start match optional_match call using where create create_unique merge set on_create_set on_match_set remove unwind delete detach_delete with with_distinct return order skip limit union call_subquery_start call_subquery_end]
- BREAK_METHODS =
          
rubocop:disable Layout/LineLength
 %w(with with_distinct call call_subquery_start call_subquery_end)
- CLAUSIFY_CLAUSE =
 proc { |method| const_get(method.to_s.split('_').map(&:capitalize).join + 'Clause') }
- CLAUSES =
 METHODS.map(&CLAUSIFY_CLAUSE)
- EMPTY =
          
Returns a CYPHER query string from the object query representation
 ' '- NEWLINE =
 "\n"
Class Attribute Summary collapse
- 
  
    
      .pretty_cypher  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
Returns the value of attribute pretty_cypher.
 
Instance Attribute Summary collapse
- 
  
    
      #clauses  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
Returns the value of attribute clauses.
 
Attributes included from QueryExt
Instance Method Summary collapse
- #&(other) ⇒ Object
 - 
  
    
      #break  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Allows what’s been built of the query so far to be frozen and the rest built anew.
 - #clause?(method) ⇒ Boolean
 - #context ⇒ Object
 - #copy ⇒ Object
 - #count(var = nil) ⇒ Object
 - 
  
    
      #create(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
CREATE clause.
 - 
  
    
      #create_unique(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
CREATE UNIQUE clause.
 - 
  
    
      #delete(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
DELETE clause.
 - 
  
    
      #detach_delete(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
DETACH DELETE clause.
 - #each ⇒ Object
 - 
  
    
      #exec  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    
Executes a query without returning the result.
 - 
  
    
      #initialize(options = {})  ⇒ Query 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    
A new instance of Query.
 - #inspect ⇒ Object
 - 
  
    
      #limit(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
LIMIT clause.
 - 
  
    
      #match(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
MATCH clause.
 - #match_nodes(hash, optional_match = false) ⇒ Object
 - 
  
    
      #merge(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
MERGE clause.
 - 
  
    
      #on_create_set(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
ON CREATE SET clause.
 - 
  
    
      #on_match_set(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
ON MATCH SET clause.
 - 
  
    
      #optional_match(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
OPTIONAL MATCH clause.
 - #optional_match_nodes(hash) ⇒ Object
 - 
  
    
      #order(*args)  ⇒ Query 
    
    
      (also: #order_by)
    
  
  
  
  
  
  
  
  
  
    
ORDER BY clause.
 - #parameters ⇒ Object
 - 
  
    
      #params(args)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Allows for the specification of values for params specified in query.
 - #partitioned_clauses ⇒ Object
 - 
  
    
      #pluck(*columns)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Return the specified columns as an array.
 - #pretty_cypher ⇒ Object
 - #print_cypher ⇒ Object
 - #raise_if_cypher_error!(response) ⇒ Object
 - 
  
    
      #remove(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
REMOVE clause.
 - 
  
    
      #reorder(*args)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Clears out previous order clauses and allows only for those specified by args.
 - #response ⇒ Object
 - 
  
    
      #return(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
RETURN clause.
 - #return_query(columns) ⇒ Object
 - 
  
    
      #set(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
SET clause.
 - 
  
    
      #set_props(*args)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Works the same as the #set method, but when given a nested array it will set properties rather than setting entire objects.
 - 
  
    
      #skip(*args)  ⇒ Query 
    
    
      (also: #offset)
    
  
  
  
  
  
  
  
  
  
    
SKIP clause.
 - 
  
    
      #start(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
START clause.
 - 
  
    
      #to_a  ⇒ Array 
    
    
  
  
  
  
  
  
  
  
  
    
Class is Enumerable.
 - #to_cypher(options = {}) ⇒ Object (also: #cypher)
 - 
  
    
      #union_cypher(other, options = {})  ⇒ String 
    
    
  
  
  
  
  
  
  
  
  
    
Returns a CYPHER query specifying the union of the callee object’s query and the argument’s query.
 - 
  
    
      #unwind(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
UNWIND clause.
 - #unwrapped ⇒ Object
 - #unwrapped? ⇒ Boolean
 - 
  
    
      #using(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
USING clause.
 - 
  
    
      #where(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
WHERE clause.
 - 
  
    
      #where_not(*args)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Works the same as the #where method, but the clause is surrounded by a Cypher NOT() function.
 - 
  
    
      #with(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
WITH clause.
 - 
  
    
      #with_distinct(*args)  ⇒ Query 
    
    
  
  
  
  
  
  
  
  
  
    
WITH clause with DISTINCT specified.
 
Methods included from QueryExt
Methods included from QueryFindInBatches
Constructor Details
#initialize(options = {}) ⇒ Query
Returns a new instance of Query.
      66 67 68 69 70 71  | 
    
      # File 'lib/active_graph/core/query.rb', line 66 def initialize( = {}) @options = @clauses = [] @_params = {} @params = Parameters.new end  | 
  
Class Attribute Details
.pretty_cypher ⇒ Object
Returns the value of attribute pretty_cypher.
      63 64 65  | 
    
      # File 'lib/active_graph/core/query.rb', line 63 def pretty_cypher @pretty_cypher end  | 
  
Instance Attribute Details
#clauses ⇒ Object
Returns the value of attribute clauses.
      17 18 19  | 
    
      # File 'lib/active_graph/core/query.rb', line 17 def clauses @clauses end  | 
  
Instance Method Details
#&(other) ⇒ Object
      371 372 373 374 375 376  | 
    
      # File 'lib/active_graph/core/query.rb', line 371 def &(other) self.class.new.tap do |new_query| new_query. = .merge(other.) new_query.clauses = clauses + other.clauses end.params(other._params) end  | 
  
#break ⇒ Object
Allows what’s been built of the query so far to be frozen and the rest built anew. Can be called multiple times in a string of method calls
      207 208 209  | 
    
      # File 'lib/active_graph/core/query.rb', line 207 def break build_deeper_query(nil) end  | 
  
#clause?(method) ⇒ Boolean
      387 388 389 390  | 
    
      # File 'lib/active_graph/core/query.rb', line 387 def clause?(method) clause_class = DEFINED_CLAUSES[method] || CLAUSIFY_CLAUSE.call(method) clauses.any? { |clause| clause.is_a?(clause_class) } end  | 
  
#context ⇒ Object
      340 341 342  | 
    
      # File 'lib/active_graph/core/query.rb', line 340 def context @options[:context] end  | 
  
#copy ⇒ Object
      378 379 380 381 382 383 384 385  | 
    
      # File 'lib/active_graph/core/query.rb', line 378 def copy dup.tap do |query| to_cypher query.instance_variable_set('@params'.freeze, @params.copy) query.instance_variable_set('@partitioned_clauses'.freeze, nil) query.instance_variable_set('@response'.freeze, nil) end end  | 
  
#count(var = nil) ⇒ Object
      256 257 258 259  | 
    
      # File 'lib/active_graph/core/query.rb', line 256 def count(var = nil) v = var.nil? ? '*' : var pluck("count(#{v})").first end  | 
  
#create_unique(*args) ⇒ Query
CREATE UNIQUE clause
| 
       | 
    
      # File 'lib/active_graph/core/query.rb', line 137
     | 
  
#detach_delete(*args) ⇒ Query
DETACH DELETE clause
      161  | 
    
      # File 'lib/active_graph/core/query.rb', line 161 METHODS = %w[start match optional_match call using where create create_unique merge set on_create_set on_match_set remove unwind delete detach_delete with with_distinct return order skip limit union call_subquery_start call_subquery_end]  | 
  
#each ⇒ Object
      261 262 263  | 
    
      # File 'lib/active_graph/core/query.rb', line 261 def each response.each { |object| yield object } end  | 
  
#exec ⇒ Boolean
Executes a query without returning the result
      273 274 275 276 277  | 
    
      # File 'lib/active_graph/core/query.rb', line 273 def exec response true end  | 
  
#inspect ⇒ Object
      73 74 75  | 
    
      # File 'lib/active_graph/core/query.rb', line 73 def inspect "#<Query CYPHER: #{ANSI::YELLOW}#{to_cypher.inspect}#{ANSI::CLEAR}>" end  | 
  
#match_nodes(hash, optional_match = false) ⇒ Object
      241 242 243 244 245 246 247 248  | 
    
      # File 'lib/active_graph/core/query.rb', line 241 def match_nodes(hash, optional_match = false) hash.inject(self) do |query, (variable, node_object)| neo_id = (node_object.respond_to?(:neo_id) ? node_object.neo_id : node_object) match_method = optional_match ? :optional_match : :match query.send(match_method, variable).where(variable => { neo_id: }) end end  | 
  
#on_create_set(*args) ⇒ Query
ON CREATE SET clause
| 
       | 
    
      # File 'lib/active_graph/core/query.rb', line 145
     | 
  
#optional_match(*args) ⇒ Query
OPTIONAL MATCH clause
| 
       | 
    
      # File 'lib/active_graph/core/query.rb', line 85
     | 
  
#optional_match_nodes(hash) ⇒ Object
      250 251 252  | 
    
      # File 'lib/active_graph/core/query.rb', line 250 def optional_match_nodes(hash) match_nodes(hash, true) end  | 
  
#order(*args) ⇒ Query Also known as: order_by
ORDER BY clause
| 
       | 
    
      # File 'lib/active_graph/core/query.rb', line 105
     | 
  
#parameters ⇒ Object
      344 345 346 347  | 
    
      # File 'lib/active_graph/core/query.rb', line 344 def parameters to_cypher merge_params end  | 
  
#params(args) ⇒ Object
Allows for the specification of values for params specified in query
      218 219 220  | 
    
      # File 'lib/active_graph/core/query.rb', line 218 def params(args) copy.tap { |new_query| new_query.instance_variable_get('@params'.freeze).add_params(args) } end  | 
  
#partitioned_clauses ⇒ Object
      349 350 351  | 
    
      # File 'lib/active_graph/core/query.rb', line 349 def partitioned_clauses @partitioned_clauses ||= PartitionedClauses.new(@clauses) end  | 
  
#pluck(*columns) ⇒ Object
Return the specified columns as an array. If one column is specified, a one-dimensional array is returned with the values of that column If two columns are specified, a n-dimensional array is returned with the values of those columns
      288 289 290 291 292 293 294 295 296 297 298 299 300  | 
    
      # File 'lib/active_graph/core/query.rb', line 288 def pluck(*columns) fail ArgumentError, 'No columns specified for Query#pluck' if columns.size.zero? query = return_query(columns) columns = query.response.keys if columns.size == 1 column = columns[0] query.map { |row| row[column] } else query.map { |row| columns.map { |column| row[column] } } end end  | 
  
#pretty_cypher ⇒ Object
      336 337 338  | 
    
      # File 'lib/active_graph/core/query.rb', line 336 def pretty_cypher to_cypher(pretty: true) end  | 
  
#print_cypher ⇒ Object
      353 354 355  | 
    
      # File 'lib/active_graph/core/query.rb', line 353 def print_cypher puts to_cypher(pretty: true).gsub(/\e[^m]+m/, '') end  | 
  
#raise_if_cypher_error!(response) ⇒ Object
      237 238 239  | 
    
      # File 'lib/active_graph/core/query.rb', line 237 def raise_if_cypher_error!(response) response.raise_cypher_error if response.respond_to?(:error?) && response.error? end  | 
  
#reorder(*args) ⇒ Object
Clears out previous order clauses and allows only for those specified by args
      182 183 184 185 186 187  | 
    
      # File 'lib/active_graph/core/query.rb', line 182 def reorder(*args) query = copy query.remove_clause_class(OrderClause) query.order(*args) end  | 
  
#response ⇒ Object
      231 232 233 234 235  | 
    
      # File 'lib/active_graph/core/query.rb', line 231 def response return @response if @response @response = ActiveGraph::Base.query(self, wrap: !unwrapped?) end  | 
  
#return_query(columns) ⇒ Object
      302 303 304 305 306 307  | 
    
      # File 'lib/active_graph/core/query.rb', line 302 def return_query(columns) query = copy query.remove_clause_class(ReturnClause) query.return(*columns) end  | 
  
#set_props(*args) ⇒ Object
Works the same as the #set method, but when given a nested array it will set properties rather than setting entire objects
      199 200 201  | 
    
      # File 'lib/active_graph/core/query.rb', line 199 def set_props(*args) # rubocop:disable Naming/AccessorMethodName build_deeper_query(SetClause, args, set_props: true) end  | 
  
#skip(*args) ⇒ Query Also known as: offset
SKIP clause
| 
       | 
    
      # File 'lib/active_graph/core/query.rb', line 113
     | 
  
#to_a ⇒ Array
Class is Enumerable. Each yield is a Hash with the key matching the variable returned and the value being the value for that key from the response
| 
       | 
    
      # File 'lib/active_graph/core/query.rb', line 265
     | 
  
#to_cypher(options = {}) ⇒ Object Also known as: cypher
      317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332  | 
    
      # File 'lib/active_graph/core/query.rb', line 317 def to_cypher( = {}) join_string = [:pretty] ? NEWLINE : EMPTY cypher_string = partitioned_clauses.map do |clauses| clauses_by_class = clauses.group_by(&:class) cypher_parts = CLAUSES.map do |clause_class| clause_class.to_cypher(clauses, [:pretty]) if clauses = clauses_by_class[clause_class] end.compact cypher_parts.join(join_string).tap(&:strip!) end.join(join_string) cypher_string = "CYPHER #{@options[:parser]} #{cypher_string}" if @options[:parser] cypher_string.tap(&:strip!) end  | 
  
#union_cypher(other, options = {}) ⇒ String
Returns a CYPHER query specifying the union of the callee object’s query and the argument’s query
      367 368 369  | 
    
      # File 'lib/active_graph/core/query.rb', line 367 def union_cypher(other, = {}) "#{to_cypher} UNION#{[:all] ? ' ALL' : ''} #{other.to_cypher}" end  | 
  
#unwrapped ⇒ Object
      222 223 224 225  | 
    
      # File 'lib/active_graph/core/query.rb', line 222 def unwrapped @_unwrapped_obj = true self end  | 
  
#unwrapped? ⇒ Boolean
      227 228 229  | 
    
      # File 'lib/active_graph/core/query.rb', line 227 def unwrapped? !!@_unwrapped_obj end  | 
  
#where_not(*args) ⇒ Object
Works the same as the #where method, but the clause is surrounded by a Cypher NOT() function
      191 192 193  | 
    
      # File 'lib/active_graph/core/query.rb', line 191 def where_not(*args) build_deeper_query(WhereClause, args, not: true) end  | 
  
#with_distinct(*args) ⇒ Query
WITH clause with DISTINCT specified
| 
       | 
    
      # File 'lib/active_graph/core/query.rb', line 101
     |