Skip to content

Commit ab9fc25

Browse files
Add MongoDB aggregation framework and analytics (v1.12.0)
* Update faraday and rack, remove rack-middleware * Bring activemodel to v8 * Add matches key in query behaviors * Add starts with , array size, time range * Pass session and opts if provided to call_function * Add aggregate pipeline functions * Add does not equal linked pointer Output aggregate pipeline Output aggregate pipeline Fix typo & add parse string processing for pointers Format with _p_ * Format _created_at and updated_at fields for aggregation pipeline * Add date conversion as well * Add verbose aggregate method * Update dates * Update query.rb * Bump minimum ruby version to 3.2 & parsestack version * Add additional sum / min / max fields * Add return pointer options for various parse queries to reduce load * Add pluck, enhanced group_by, and sortable grouping to Query Introduces a pluck method for extracting field values from query results, enhances group_by and group_by_date to support array flattening, pointer conversion, and sortable results, and adds GroupedResult, SortableGroupBy, and SortableGroupByDate classes for flexible aggregation and sorting. Also adds group_objects_by for grouping actual objects in Ruby. Improves documentation and extensibility for advanced aggregation use cases. * Reorder sorotable * Add new feature tests * Add to_table functions * table tests and sorting * Adjust tests * Update query.rb * Update query.rb * Refactor aggregation logic and add Aggregation helper class Refactored aggregation-related methods in Parse::Query to use a new Aggregation helper class for executing MongoDB pipelines. This improves code reuse, consistency, and testability for aggregation operations such as distinct, count_distinct, and group_by. Updated related tests to focus on core logic and pointer conversion, and added new utility methods for raw results and pointer extraction. * Add pipeline aggregation * Recheck pointers * process pointers * Fix dates * Fix dates again * Return parse pointers instead of mongodb strings * distinct by default will return all ids * Change version to 1.12.0 * Adjust changes and readme * Update parse-stack.gemspec Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update test/lib/parse/query/aggregation_features_test.rb Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Adjust typos --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 1a037ee commit ab9fc25

41 files changed

Lines changed: 6029 additions & 151 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.solargraph.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ max_files: 5000
1515
require:
1616
- activemodel
1717
- faraday
18-
- faraday_middleware
1918
- moneta
2019
- activesupport
2120
- rack

.travis.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
language: ruby
22
rvm:
3-
- 2.6
4-
- 2.7
53
- 3.1.2
64
before_install:
75
- yes | gem update --system --force

Changes.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,67 @@
11
## Parse-Stack Changelog
22

3+
### 1.12.0
4+
5+
#### Breaking Changes
6+
- **BREAKING**: `distinct` method now returns object IDs directly by default for pointer fields instead of full pointer hash objects like `{"__type"=>"Pointer", "className"=>"Team", "objectId"=>"abc123"}`. Use `distinct(field, return_pointers: true)` to get Parse::Pointer objects.
7+
- **BREAKING**: Minimum Ruby version is now 3.2+ (dropped support for Ruby < 3.2)
8+
- **BREAKING**: Updated to Faraday 2.x and removed `faraday_middleware` dependency
9+
- **BREAKING**: Fixed typo "constaint" to "constraint" throughout codebase
10+
11+
#### New Aggregation Functions
12+
- NEW: `sum(field)` - Calculate sum of numeric values across matching records
13+
- NEW: `min(field)` - Find minimum value for a field
14+
- NEW: `max(field)` - Find maximum value for a field
15+
- NEW: `average(field)` / `avg(field)` - Calculate average value for numeric fields
16+
- NEW: `count_distinct(field)` - Count unique values using MongoDB aggregation pipeline
17+
18+
#### Enhanced Group By Operations
19+
- NEW: `group_by(field, options)` - Group records by field value with aggregation support
20+
- NEW: `group_by_date(field, interval, options)` - Group by date intervals (:year, :month, :week, :day, :hour)
21+
- NEW: `group_objects_by(field, options)` - Group actual object instances (not aggregated)
22+
- NEW: Sortable grouping with `sortable: true` option and `SortableGroupBy`/`SortableGroupByDate` classes
23+
- NEW: Array flattening with `flatten_arrays: true` for multi-value fields
24+
- NEW: Pointer optimization with `return_pointers: true` for memory efficiency
25+
26+
#### Advanced Query Constraints
27+
- NEW: `equals_linked_pointer` - Compare pointer fields across linked objects using aggregation
28+
- NEW: `does_not_equal_linked_pointer` - Negative comparison of linked pointers
29+
- NEW: `between_dates` - Query records within date/time ranges
30+
- NEW: `matches_key_in_query` - Matches key in subquery
31+
- NEW: `does_not_match_key_in_query` - Does not match key in subquery
32+
- NEW: `starts_with` - String prefix matching constraint
33+
- NEW: `contains` - String substring matching constraint
34+
- NEW: `array_size` - Array length constraint
35+
36+
#### New Utility Methods
37+
- NEW: `pluck(field)` - Extract values for single field from all matching records
38+
- NEW: `to_table(columns, options)` - Format results as ASCII/CSV/JSON tables with sorting
39+
- NEW: `verbose_aggregate` - Debug flag for MongoDB aggregation pipeline details
40+
- NEW: `keys(*fields)` / `select_fields(*fields)` - Field selection optimization
41+
- NEW: `result_pointers` - Get Parse::Pointer objects instead of full objects
42+
- NEW: `distinct_objects(field)` - Get distinct values with populated objects
43+
44+
#### Enhanced Cloud Functions
45+
- NEW: `call_function_with_session(name, body, session_token)` - Call cloud functions with session context
46+
- NEW: `trigger_job_with_session(name, body, session_token)` - Trigger background jobs with session token
47+
- NEW: Enhanced authentication options and master key support for cloud functions
48+
49+
#### Result Processing & Display
50+
- NEW: `GroupedResult` class with built-in sorting capabilities (`sort_by_key_asc/desc`, `sort_by_value_asc/desc`)
51+
- NEW: Table formatting with custom headers, sorting, and multiple output formats (ASCII, CSV, JSON)
52+
- NEW: Enhanced result processing with pointer optimization across all aggregation methods
53+
54+
#### Pointer & Object Handling Improvements
55+
- IMPROVED: Enhanced `distinct` with automatic detection and conversion of MongoDB pointer strings
56+
- IMPROVED: `return_pointers` option available across multiple methods for memory optimization
57+
- IMPROVED: Server-side object population in aggregation pipelines
58+
- IMPROVED: Automatic handling of `ClassName$objectId` format conversion
59+
60+
#### Dependency Updates
61+
- UPDATED: ActiveModel and ActiveSupport to latest compatible versions
62+
- UPDATED: Rack dependency
63+
- UPDATED: Modernized for Ruby 3.2+ compatibility
64+
365
### 1.11.3
466
- Adds "empty" query constraint option
567
- Adds "include" alias for "includes" query method

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ group :test, :development do
1616
gem "yard", ">= 0.9.11"
1717
gem "redcarpet"
1818
gem "rufo"
19-
gem "thin" # for yard server
19+
# gem "thin" # for yard server - disabled due to eventmachine compilation issues
2020
end

Gemfile.lock

Lines changed: 80 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,101 @@
11
PATH
22
remote: .
33
specs:
4-
parse-stack (1.9.1)
4+
parse-stack (1.12.0)
55
active_model_serializers (>= 0.9, < 1)
6-
activemodel (>= 5, < 7)
7-
activesupport (>= 5, < 7)
8-
faraday (< 1)
9-
faraday_middleware (>= 0.9, < 2)
6+
activemodel (>= 5, < 9)
7+
activesupport (>= 5, < 9)
8+
faraday (~> 2.0)
109
moneta (< 2)
1110
parallel (>= 1.6, < 2)
12-
rack (>= 2.0.6, < 3)
11+
rack (>= 2.0.6, < 4)
1312

1413
GEM
1514
remote: https://rubygems.org/
1615
specs:
17-
actionpack (6.1.7.1)
18-
actionview (= 6.1.7.1)
19-
activesupport (= 6.1.7.1)
20-
rack (~> 2.0, >= 2.0.9)
16+
actionpack (8.0.2.1)
17+
actionview (= 8.0.2.1)
18+
activesupport (= 8.0.2.1)
19+
nokogiri (>= 1.8.5)
20+
rack (>= 2.2.4)
21+
rack-session (>= 1.0.1)
2122
rack-test (>= 0.6.3)
22-
rails-dom-testing (~> 2.0)
23-
rails-html-sanitizer (~> 1.0, >= 1.2.0)
24-
actionview (6.1.7.1)
25-
activesupport (= 6.1.7.1)
23+
rails-dom-testing (~> 2.2)
24+
rails-html-sanitizer (~> 1.6)
25+
useragent (~> 0.16)
26+
actionview (8.0.2.1)
27+
activesupport (= 8.0.2.1)
2628
builder (~> 3.1)
27-
erubi (~> 1.4)
28-
rails-dom-testing (~> 2.0)
29-
rails-html-sanitizer (~> 1.1, >= 1.2.0)
30-
active_model_serializers (0.10.13)
31-
actionpack (>= 4.1, < 7.1)
32-
activemodel (>= 4.1, < 7.1)
29+
erubi (~> 1.11)
30+
rails-dom-testing (~> 2.2)
31+
rails-html-sanitizer (~> 1.6)
32+
active_model_serializers (0.10.15)
33+
actionpack (>= 4.1)
34+
activemodel (>= 4.1)
3335
case_transform (>= 0.2)
3436
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
35-
activemodel (6.1.7.1)
36-
activesupport (= 6.1.7.1)
37-
activesupport (6.1.7.1)
38-
concurrent-ruby (~> 1.0, >= 1.0.2)
37+
activemodel (8.0.2.1)
38+
activesupport (= 8.0.2.1)
39+
activesupport (8.0.2.1)
40+
base64
41+
benchmark (>= 0.3)
42+
bigdecimal
43+
concurrent-ruby (~> 1.0, >= 1.3.1)
44+
connection_pool (>= 2.2.5)
45+
drb
3946
i18n (>= 1.6, < 2)
47+
logger (>= 1.4.2)
4048
minitest (>= 5.1)
41-
tzinfo (~> 2.0)
42-
zeitwerk (~> 2.3)
49+
securerandom (>= 0.3)
50+
tzinfo (~> 2.0, >= 2.0.5)
51+
uri (>= 0.13.1)
4352
ansi (1.5.0)
53+
base64 (0.3.0)
54+
benchmark (0.4.1)
55+
bigdecimal (3.2.2)
4456
binding_of_caller (1.0.0)
4557
debug_inspector (>= 0.0.1)
46-
builder (3.2.4)
58+
builder (3.3.0)
4759
byebug (11.1.3)
4860
case_transform (0.2)
4961
activesupport
5062
coderay (1.1.3)
51-
concurrent-ruby (1.1.10)
52-
connection_pool (2.3.0)
63+
concurrent-ruby (1.3.5)
64+
connection_pool (2.5.3)
5365
crass (1.0.6)
54-
daemons (1.4.1)
5566
debug_inspector (1.1.0)
5667
dotenv (2.8.1)
57-
erubi (1.12.0)
58-
eventmachine (1.2.7)
59-
faraday (0.17.6)
60-
multipart-post (>= 1.2, < 3)
61-
faraday_middleware (0.14.0)
62-
faraday (>= 0.7.4, < 1.0)
63-
i18n (1.12.0)
68+
drb (2.2.3)
69+
erubi (1.13.1)
70+
faraday (2.13.4)
71+
faraday-net_http (>= 2.0, < 3.5)
72+
json
73+
logger
74+
faraday-net_http (3.4.1)
75+
net-http (>= 0.5.0)
76+
i18n (1.14.7)
6477
concurrent-ruby (~> 1.0)
78+
json (2.13.2)
6579
jsonapi-renderer (0.2.2)
66-
loofah (2.19.1)
80+
logger (1.7.0)
81+
loofah (2.24.1)
6782
crass (~> 1.0.2)
68-
nokogiri (>= 1.5.9)
83+
nokogiri (>= 1.12.0)
6984
method_source (1.0.0)
70-
mini_portile2 (2.8.1)
71-
minitest (5.17.0)
72-
minitest-reporters (1.5.0)
85+
mini_portile2 (2.8.9)
86+
minitest (5.25.5)
87+
minitest-reporters (1.7.1)
7388
ansi
7489
builder
7590
minitest (>= 5.0)
7691
ruby-progressbar
77-
moneta (1.5.2)
78-
multipart-post (2.2.3)
79-
nokogiri (1.13.10)
80-
mini_portile2 (~> 2.8.0)
92+
moneta (1.6.0)
93+
net-http (0.6.0)
94+
uri
95+
nokogiri (1.18.9)
96+
mini_portile2 (~> 2.8.2)
8197
racc (~> 1.4)
82-
parallel (1.22.1)
98+
parallel (1.27.0)
8399
pry (0.14.2)
84100
coderay (~> 1.1)
85101
method_source (~> 1.0)
@@ -88,33 +104,36 @@ GEM
88104
pry-stack_explorer (0.6.1)
89105
binding_of_caller (~> 1.0)
90106
pry (~> 0.13)
91-
racc (1.6.2)
92-
rack (2.2.6.2)
93-
rack-test (2.0.2)
107+
racc (1.8.1)
108+
rack (3.2.0)
109+
rack-session (2.1.1)
110+
base64 (>= 0.1.0)
111+
rack (>= 3.0.0)
112+
rack-test (2.2.0)
94113
rack (>= 1.3)
95-
rails-dom-testing (2.0.3)
96-
activesupport (>= 4.2.0)
114+
rails-dom-testing (2.3.0)
115+
activesupport (>= 5.0.0)
116+
minitest
97117
nokogiri (>= 1.6)
98-
rails-html-sanitizer (1.5.0)
99-
loofah (~> 2.19, >= 2.19.1)
118+
rails-html-sanitizer (1.6.2)
119+
loofah (~> 2.21)
120+
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
100121
rake (13.0.6)
101122
redcarpet (3.5.1)
102123
redis (5.0.6)
103124
redis-client (>= 0.9.0)
104125
redis-client (0.12.1)
105126
connection_pool
106-
ruby-progressbar (1.11.0)
127+
ruby-progressbar (1.13.0)
107128
rufo (0.13.0)
108-
thin (1.8.1)
109-
daemons (~> 1.0, >= 1.0.9)
110-
eventmachine (~> 1.0, >= 1.0.4)
111-
rack (>= 1, < 3)
112-
tzinfo (2.0.5)
129+
securerandom (0.4.1)
130+
tzinfo (2.0.6)
113131
concurrent-ruby (~> 1.0)
132+
uri (1.0.3)
133+
useragent (0.16.11)
114134
webrick (1.7.0)
115135
yard (0.9.28)
116136
webrick (~> 1.7.0)
117-
zeitwerk (2.6.6)
118137

119138
PLATFORMS
120139
ruby
@@ -132,7 +151,6 @@ DEPENDENCIES
132151
redcarpet
133152
redis
134153
rufo
135-
thin
136154
yard (>= 0.9.11)
137155

138156
BUNDLED WITH

0 commit comments

Comments
 (0)