Class: Parse::Aggregation
- Inherits:
-
Object
- Object
- Parse::Aggregation
- Defined in:
- lib/parse/query.rb
Overview
Helper class for executing arbitrary MongoDB aggregation pipelines. Provides a consistent interface with results, raw, and result_pointers methods.
Instance Attribute Summary collapse
-
#mongo_direct ⇒ Boolean
readonly
Whether #execute! will route through MongoDB.aggregate instead of Parse Server's REST
/aggregateendpoint. -
#pipeline ⇒ Array<Hash>
readonly
The MongoDB aggregation pipeline stages this Aggregation will execute.
Instance Method Summary collapse
-
#add_stages(*stages) ⇒ Aggregation
Add additional pipeline stages.
-
#any? ⇒ Boolean
Check if there are any results.
-
#count ⇒ Integer
Returns the count of results.
-
#empty? ⇒ Boolean
Check if there are no results.
-
#execute! ⇒ Parse::Response, Array
Execute the aggregation pipeline and cache the response.
-
#execute_direct!(max_time_ms: @max_time_ms) ⇒ Array<Hash>
Execute aggregation directly on MongoDB.
-
#first(limit = 1) ⇒ Parse::Object+
Returns the first result from the aggregation.
-
#initialize(query, pipeline, verbose: nil, mongo_direct: false, max_time_ms: nil) ⇒ Aggregation
constructor
A new instance of Aggregation.
-
#raw { ... } ⇒ Array<Hash>
Returns raw unprocessed results from the aggregation.
-
#result_pointers { ... } ⇒ Array<Parse::Pointer>
(also: #results_pointers)
Returns only pointer objects for all matching results.
-
#results { ... } ⇒ Array<Parse::Object, AggregationResult>
(also: #all)
Returns processed results from the aggregation.
-
#with_stages(*stages) ⇒ Aggregation
Create a new Aggregation with additional stages (non-mutating).
Constructor Details
#initialize(query, pipeline, verbose: nil, mongo_direct: false, max_time_ms: nil) ⇒ Aggregation
Returns a new instance of Aggregation.
5506 5507 5508 5509 5510 5511 5512 5513 5514 |
# File 'lib/parse/query.rb', line 5506 def initialize(query, pipeline, verbose: nil, mongo_direct: false, max_time_ms: nil) @query = query @pipeline = pipeline @cached_response = nil @mongo_direct = mongo_direct @max_time_ms = max_time_ms # Use provided verbose setting, or fall back to query's verbose_aggregate setting @verbose = verbose.nil? ? @query.instance_variable_get(:@verbose_aggregate) : verbose end |
Instance Attribute Details
#mongo_direct ⇒ Boolean (readonly)
Returns whether #execute! will route through
MongoDB.aggregate instead of Parse Server's REST
/aggregate endpoint.
5498 5499 5500 |
# File 'lib/parse/query.rb', line 5498 def mongo_direct @mongo_direct end |
#pipeline ⇒ Array<Hash> (readonly)
Returns the MongoDB aggregation pipeline stages this Aggregation will execute. Useful for previewing the routed pipeline before #execute!, for snapshot-based regression tests, and for debugging the REST-vs-mongo-direct translation.
5493 5494 5495 |
# File 'lib/parse/query.rb', line 5493 def pipeline @pipeline end |
Instance Method Details
#add_stages(*stages) ⇒ Aggregation
Add additional pipeline stages
5711 5712 5713 5714 5715 |
# File 'lib/parse/query.rb', line 5711 def add_stages(*stages) @pipeline.concat(stages.flatten) @cached_response = nil # Clear cache when pipeline changes self end |
#any? ⇒ Boolean
Check if there are any results
5698 5699 5700 |
# File 'lib/parse/query.rb', line 5698 def any? count > 0 end |
#count ⇒ Integer
Returns the count of results
5687 5688 5689 5690 5691 5692 5693 5694 |
# File 'lib/parse/query.rb', line 5687 def count response = execute! if @mongo_direct && defined?(Parse::MongoDB) && Parse::MongoDB.enabled? response.nil? ? 0 : response.count else response.error? ? 0 : response.result.count end end |
#empty? ⇒ Boolean
Check if there are no results
5704 5705 5706 |
# File 'lib/parse/query.rb', line 5704 def empty? count == 0 end |
#execute! ⇒ Parse::Response, Array
Execute the aggregation pipeline and cache the response
5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 |
# File 'lib/parse/query.rb', line 5518 def execute! return @cached_response if @cached_response if @verbose puts "[VERBOSE AGGREGATE] Custom aggregation pipeline:" puts JSON.pretty_generate(@pipeline) puts "[VERBOSE AGGREGATE] Sending to: #{@query.instance_variable_get(:@table)}" puts "[VERBOSE AGGREGATE] Using MongoDB direct: #{@mongo_direct}" end if @mongo_direct && defined?(Parse::MongoDB) && Parse::MongoDB.enabled? @cached_response = execute_direct! else @cached_response = @query.client.aggregate_pipeline( @query.instance_variable_get(:@table), @pipeline, headers: {}, **@query.send(:_opts), ) end if @verbose if @mongo_direct && defined?(Parse::MongoDB) && Parse::MongoDB.enabled? puts "[VERBOSE AGGREGATE] Response result count: #{@cached_response&.count}" else puts "[VERBOSE AGGREGATE] Response success?: #{@cached_response.success?}" puts "[VERBOSE AGGREGATE] Response result count: #{@cached_response.result&.count}" end end @cached_response end |
#execute_direct!(max_time_ms: @max_time_ms) ⇒ Array<Hash>
Execute aggregation directly on MongoDB
5555 5556 5557 5558 5559 |
# File 'lib/parse/query.rb', line 5555 def execute_direct!(max_time_ms: @max_time_ms) table = @query.instance_variable_get(:@table) auth_kwargs = @query.send(:mongo_direct_auth_kwargs) Parse::MongoDB.aggregate(table, @pipeline, max_time_ms: max_time_ms, **auth_kwargs) end |
#first(limit = 1) ⇒ Parse::Object+
Returns the first result from the aggregation
5680 5681 5682 5683 |
# File 'lib/parse/query.rb', line 5680 def first(limit = 1) items = results.first(limit) limit == 1 ? items.first : items end |
#raw { ... } ⇒ Array<Hash>
Returns raw unprocessed results from the aggregation
5644 5645 5646 5647 5648 5649 5650 5651 5652 |
# File 'lib/parse/query.rb', line 5644 def raw(&block) response = execute! return [] if response.respond_to?(:error?) && response.error? items = response.respond_to?(:result) ? response.result : response items = [] unless items.is_a?(Array) return items.each(&block) if block_given? items end |
#result_pointers { ... } ⇒ Array<Parse::Pointer> Also known as: results_pointers
Returns only pointer objects for all matching results
5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 |
# File 'lib/parse/query.rb', line 5657 def result_pointers(&block) response = execute! if @mongo_direct && defined?(Parse::MongoDB) && Parse::MongoDB.enabled? return [] if response.nil? || response.empty? # Convert MongoDB results to Parse format first converted = Parse::MongoDB.convert_documents_to_parse(response, @query.instance_variable_get(:@table)) items = @query.send(:to_pointers, converted) else return [] if response.error? items = @query.send(:to_pointers, response.result) end return items.each(&block) if block_given? items end |
#results { ... } ⇒ Array<Parse::Object, AggregationResult> Also known as: all
Returns processed results from the aggregation.
- Standard Parse documents (with objectId) are returned as Parse::Object instances
- Custom aggregation results (from $group, $project, etc.) are returned as AggregationResult objects that support both hash access and method access
5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 |
# File 'lib/parse/query.rb', line 5568 def results(&block) response = execute! if @mongo_direct && defined?(Parse::MongoDB) && Parse::MongoDB.enabled? # For MongoDB direct, branch per-row on the *raw* document: real Parse # docs always carry _created_at / _updated_at, while $group rows reuse # _id as the group key. We must not feed group rows through # convert_document_to_parse, which would rename _id → objectId and # fool the Parse-document heuristic. return [] if response.nil? || response.empty? table = @query.instance_variable_get(:@table) items = response.map { |raw| convert_direct_aggregation_item(raw, table) } else return [] if response.error? items = response.result.map { |item| convert_aggregation_item(item) } end return items.each(&block) if block_given? items end |
#with_stages(*stages) ⇒ Aggregation
Create a new Aggregation with additional stages (non-mutating)
5720 5721 5722 |
# File 'lib/parse/query.rb', line 5720 def with_stages(*stages) Aggregation.new(@query, @pipeline + stages.flatten, verbose: @verbose) end |