elasticgraph-graphql 0.18.0.0 → 0.18.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b19df00bc750f39aa2cbccab58af18c6cb2a2329017e9d0aa8f889dce5b1c377
4
- data.tar.gz: 8308fce167bd7cf625bb7b82f2f717c174ffa12655b1df77e58e37369b8d6294
3
+ metadata.gz: b9832ca5ee58e052ef3428907d2bc277cdeba8b567eb3a3861609d0b97799ff7
4
+ data.tar.gz: 74f29fcd9a89007b34a2b4be5ba332dabc4ff7cb38585a0173e89541061a65a6
5
5
  SHA512:
6
- metadata.gz: c983f82a5da8da47c2f8146337b9425623d1ebfacf0e2f93db706cd53e465725f12cc43fe4e49d2b7885422a428e7744ae61642264941d3d497eb4d4fd3bc9f6
7
- data.tar.gz: 277958b0fee144f62342f2e3081f4ebbb9a7529456e62a2b5183ad8fe93f2cca7fd5013cbe9bf461fceee46d5f42cea8149d40b624410fbb9498267e78d1dedb
6
+ metadata.gz: 9ff8132bb4c647b2f23669d7c8e5993da3550b83fc15113ebcd0234a19f6f1faf79bfe2127c03d5cf19f39beadf3f96abcbbd18e99df22dd6bba3d1931e86524
7
+ data.tar.gz: 7ac54e755f0d20da132d7ff2ca03a9c3f61b2c182c781408e50ba9ac2e20c45a12dbf6dd235010b73675ee8b6be1bc7d352d868dd8c0aa982671b85e23bf41ed
@@ -7,6 +7,7 @@
7
7
  # frozen_string_literal: true
8
8
 
9
9
  require "elastic_graph/graphql/aggregation/field_path_encoder"
10
+ require "elastic_graph/support/memoizable_data"
10
11
 
11
12
  module ElasticGraph
12
13
  class GraphQL
@@ -14,14 +15,23 @@ module ElasticGraph
14
15
  # Represents a sub-aggregation on a `nested` field.
15
16
  # For the relevant Elasticsearch docs, see:
16
17
  # https://www.elastic.co/guide/en/elasticsearch/reference/8.10/search-aggregations-bucket-nested-aggregation.html
17
- class NestedSubAggregation < ::Data.define(:nested_path, :query)
18
+ class NestedSubAggregation < Support::MemoizableData.define(:nested_path, :query)
19
+ # The nested path in the GraphQL query from the parent aggregation to this-subaggregation, encoded
20
+ # for use as a hash key.
21
+ #
22
+ # This key will be unique in the scope of the parent aggregation query, and thus suitable as a key
23
+ # in a sub-aggregations hash.
24
+ def nested_path_key
25
+ @nested_path_key ||= FieldPathEncoder.encode(nested_path.map(&:name_in_graphql_query))
26
+ end
27
+
18
28
  def build_agg_hash(filter_interpreter, parent_queries:)
19
29
  detail = query.build_agg_detail(filter_interpreter, field_path: nested_path, parent_queries: parent_queries)
20
30
  return {} if detail.nil?
21
31
 
22
- query_names = parent_queries.map(&:name) + [query.name]
32
+ parent_query_names = parent_queries.map(&:name)
23
33
  {
24
- Key.encode(query_names) => {
34
+ Key.encode(parent_query_names + [nested_path_key]) => {
25
35
  "nested" => {"path" => FieldPathEncoder.encode(nested_path.filter_map(&:name_in_index))},
26
36
  "aggs" => detail.clauses,
27
37
  "meta" => detail.meta.merge({
@@ -9,6 +9,7 @@
9
9
  require "elastic_graph/graphql/aggregation/key"
10
10
  require "elastic_graph/graphql/datastore_query"
11
11
  require "elastic_graph/graphql/filtering/field_path"
12
+ require "elastic_graph/support/hash_util"
12
13
 
13
14
  module ElasticGraph
14
15
  class GraphQL
@@ -62,7 +63,7 @@ module ElasticGraph
62
63
 
63
64
  filter_detail(filter_interpreter, field_path) do
64
65
  grouping_adapter.grouping_detail_for(self) do
65
- computations_detail.merge(sub_aggregation_detail(filter_interpreter, queries))
66
+ Support::HashUtil.disjoint_merge(computations_detail, sub_aggregation_detail(filter_interpreter, queries))
66
67
  end
67
68
  end
68
69
  end
@@ -114,7 +115,10 @@ module ElasticGraph
114
115
  end
115
116
 
116
117
  def build_inner_aggregation_detail(collection, &block)
117
- collection.map(&block).reduce({}, :merge)
118
+ initial = {} # : ::Hash[::String, untyped]
119
+ collection.map(&block).reduce(initial) do |accum, hash|
120
+ Support::HashUtil.disjoint_merge(accum, hash)
121
+ end
118
122
  end
119
123
  end
120
124
 
@@ -15,6 +15,7 @@ require "elastic_graph/graphql/aggregation/path_segment"
15
15
  require "elastic_graph/graphql/aggregation/query"
16
16
  require "elastic_graph/graphql/aggregation/script_term_grouping"
17
17
  require "elastic_graph/graphql/schema/arguments"
18
+ require "elastic_graph/support/hash_util"
18
19
  require "elastic_graph/support/memoizable_data"
19
20
 
20
21
  module ElasticGraph
@@ -303,22 +304,25 @@ module ElasticGraph
303
304
  end
304
305
 
305
306
  def build_sub_aggregations_from(node_node, parent_nested_path: [])
306
- build_clauses_from(node_node.selection(element_names.sub_aggregations)) do |node, field, field_path|
307
- if field.type.elasticgraph_category == :nested_sub_aggregation_connection
308
- nested_path = parent_nested_path + field_path
309
- nested_sub_agg = NestedSubAggregation.new(
310
- nested_path: nested_path,
311
- query: build_aggregation_query_for(
312
- node,
313
- field: field,
314
- grouping_adapter: sub_aggregation_grouping_adapter,
315
- nested_path: nested_path
307
+ key_sub_agg_pairs =
308
+ build_clauses_from(node_node.selection(element_names.sub_aggregations)) do |node, field, field_path|
309
+ if field.type.elasticgraph_category == :nested_sub_aggregation_connection
310
+ nested_path = parent_nested_path + field_path
311
+ nested_sub_agg = NestedSubAggregation.new(
312
+ nested_path: nested_path,
313
+ query: build_aggregation_query_for(
314
+ node,
315
+ field: field,
316
+ grouping_adapter: sub_aggregation_grouping_adapter,
317
+ nested_path: nested_path
318
+ )
316
319
  )
317
- )
318
320
 
319
- [[nested_sub_agg.query.name, nested_sub_agg]]
321
+ [[nested_sub_agg.nested_path_key, nested_sub_agg]] # : ::Array[[::String, NestedSubAggregation]]
322
+ end
320
323
  end
321
- end.to_h
324
+
325
+ Support::HashUtil.strict_to_h(key_sub_agg_pairs)
322
326
  end
323
327
 
324
328
  def build_paginator_for(node)
@@ -8,6 +8,7 @@
8
8
 
9
9
  require "elastic_graph/graphql/aggregation/key"
10
10
  require "elastic_graph/graphql/aggregation/path_segment"
11
+ require "elastic_graph/support/hash_util"
11
12
 
12
13
  module ElasticGraph
13
14
  class GraphQL
@@ -27,7 +28,7 @@ module ElasticGraph
27
28
  function_name: field.name_in_index.to_s
28
29
  )
29
30
 
30
- result = bucket.fetch(key.encode)
31
+ result = Support::HashUtil.verbose_fetch(bucket, key.encode)
31
32
 
32
33
  # Aggregated value results always have a `value` key; in addition, for `date` field, they also have a `value_as_string`.
33
34
  # In that case, `value` is a number (e.g. ms since epoch) whereas `value_as_string` is a formatted value. ElasticGraph
@@ -7,6 +7,7 @@
7
7
  # frozen_string_literal: true
8
8
 
9
9
  require "elastic_graph/graphql/aggregation/field_path_encoder"
10
+ require "elastic_graph/support/hash_util"
10
11
 
11
12
  module ElasticGraph
12
13
  class GraphQL
@@ -21,7 +22,8 @@ module ElasticGraph
21
22
  new_field_path = field_path + [PathSegment.for(field: field, lookahead: lookahead)]
22
23
  return with(field_path: new_field_path) if field.type.object?
23
24
 
24
- bucket.fetch("key").fetch(FieldPathEncoder.encode(new_field_path.map(&:name_in_graphql_query)))
25
+ bucket_entry = Support::HashUtil.verbose_fetch(bucket, "key")
26
+ Support::HashUtil.verbose_fetch(bucket_entry, FieldPathEncoder.encode(new_field_path.map(&:name_in_graphql_query)))
25
27
  end
26
28
  end
27
29
  end
@@ -7,17 +7,19 @@
7
7
  # frozen_string_literal: true
8
8
 
9
9
  require "elastic_graph/graphql/aggregation/composite_grouping_adapter"
10
+ require "elastic_graph/graphql/aggregation/field_path_encoder"
10
11
  require "elastic_graph/graphql/aggregation/key"
11
12
  require "elastic_graph/graphql/aggregation/non_composite_grouping_adapter"
12
13
  require "elastic_graph/graphql/aggregation/resolvers/count_detail"
13
14
  require "elastic_graph/graphql/decoded_cursor"
14
15
  require "elastic_graph/graphql/resolvers/resolvable_value"
16
+ require "elastic_graph/support/hash_util"
15
17
 
16
18
  module ElasticGraph
17
19
  class GraphQL
18
20
  module Aggregation
19
21
  module Resolvers
20
- class SubAggregations < ::Data.define(:schema_element_names, :sub_aggregations, :parent_queries, :sub_aggs_by_name, :field_path)
22
+ class SubAggregations < ::Data.define(:schema_element_names, :sub_aggregations, :parent_queries, :sub_aggs_by_agg_key, :field_path)
21
23
  def can_resolve?(field:, object:)
22
24
  true
23
25
  end
@@ -27,25 +29,26 @@ module ElasticGraph
27
29
  new_field_path = field_path + [path_segment]
28
30
  return with(field_path: new_field_path) unless field.type.elasticgraph_category == :nested_sub_aggregation_connection
29
31
 
30
- aggregation_name = path_segment.name_in_graphql_query
31
- sub_agg_query = sub_aggregations.fetch(aggregation_name).query
32
+ sub_agg_key = FieldPathEncoder.encode(new_field_path.map(&:name_in_graphql_query))
33
+ sub_agg_query = Support::HashUtil.verbose_fetch(sub_aggregations, sub_agg_key).query
32
34
 
33
35
  RelayConnectionBuilder.build_from_buckets(
34
36
  query: sub_agg_query,
35
37
  parent_queries: parent_queries,
36
38
  schema_element_names: schema_element_names,
37
39
  field_path: new_field_path
38
- ) { extract_buckets(aggregation_name, args) }
40
+ ) { extract_buckets(sub_agg_key, args) }
39
41
  end
40
42
 
41
43
  private
42
44
 
43
- def extract_buckets(aggregation_name, args)
45
+ def extract_buckets(aggregation_field_path, args)
44
46
  # When the client passes `first: 0`, we omit the sub-aggregation from the query body entirely,
45
- # and it wont' be in `sub_aggs_by_name`. Instead, we can just return an empty list of buckets.
47
+ # and it wont' be in `sub_aggs_by_agg_key`. Instead, we can just return an empty list of buckets.
46
48
  return [] if args[schema_element_names.first] == 0
47
49
 
48
- sub_agg = sub_aggs_by_name.fetch(Key.encode(parent_queries.map(&:name) + [aggregation_name]))
50
+ sub_agg_key = Key.encode(parent_queries.map(&:name) + [aggregation_field_path])
51
+ sub_agg = Support::HashUtil.verbose_fetch(sub_aggs_by_agg_key, sub_agg_key)
49
52
  meta = sub_agg.fetch("meta")
50
53
 
51
54
  # When the sub-aggregation node of the GraphQL query has a `filter` argument, the direct sub-aggregation returned by
@@ -8,6 +8,7 @@
8
8
 
9
9
  require "elastic_graph/graphql/aggregation/resolvers/relay_connection_builder"
10
10
  require "elastic_graph/graphql/resolvers/relay_connection/search_response_adapter_builder"
11
+ require "elastic_graph/support/hash_util"
11
12
 
12
13
  module ElasticGraph
13
14
  class GraphQL
@@ -33,7 +34,7 @@ module ElasticGraph
33
34
  Aggregation::Resolvers::RelayConnectionBuilder.build_from_search_response(
34
35
  schema_element_names: schema_element_names,
35
36
  search_response: search_response,
36
- query: query.aggregations.fetch(agg_name)
37
+ query: Support::HashUtil.verbose_fetch(query.aggregations, agg_name)
37
38
  )
38
39
  end
39
40
  end
@@ -171,7 +171,6 @@ module ElasticGraph
171
171
  # @private
172
172
  def datastore_query_adapters
173
173
  @datastore_query_adapters ||= begin
174
- require "elastic_graph/graphql/aggregation/non_composite_grouping_adapter"
175
174
  require "elastic_graph/graphql/aggregation/query_adapter"
176
175
  require "elastic_graph/graphql/query_adapter/filters"
177
176
  require "elastic_graph/graphql/query_adapter/pagination"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticgraph-graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0.0
4
+ version: 0.18.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Myron Marston
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-27 00:00:00.000000000 Z
11
+ date: 2024-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop-factory_bot
@@ -278,28 +278,28 @@ dependencies:
278
278
  requirements:
279
279
  - - '='
280
280
  - !ruby/object:Gem::Version
281
- version: 0.18.0.0
281
+ version: 0.18.0.1
282
282
  type: :runtime
283
283
  prerelease: false
284
284
  version_requirements: !ruby/object:Gem::Requirement
285
285
  requirements:
286
286
  - - '='
287
287
  - !ruby/object:Gem::Version
288
- version: 0.18.0.0
288
+ version: 0.18.0.1
289
289
  - !ruby/object:Gem::Dependency
290
290
  name: elasticgraph-schema_artifacts
291
291
  requirement: !ruby/object:Gem::Requirement
292
292
  requirements:
293
293
  - - '='
294
294
  - !ruby/object:Gem::Version
295
- version: 0.18.0.0
295
+ version: 0.18.0.1
296
296
  type: :runtime
297
297
  prerelease: false
298
298
  version_requirements: !ruby/object:Gem::Requirement
299
299
  requirements:
300
300
  - - '='
301
301
  - !ruby/object:Gem::Version
302
- version: 0.18.0.0
302
+ version: 0.18.0.1
303
303
  - !ruby/object:Gem::Dependency
304
304
  name: graphql
305
305
  requirement: !ruby/object:Gem::Requirement
@@ -326,70 +326,70 @@ dependencies:
326
326
  requirements:
327
327
  - - '='
328
328
  - !ruby/object:Gem::Version
329
- version: 0.18.0.0
329
+ version: 0.18.0.1
330
330
  type: :development
331
331
  prerelease: false
332
332
  version_requirements: !ruby/object:Gem::Requirement
333
333
  requirements:
334
334
  - - '='
335
335
  - !ruby/object:Gem::Version
336
- version: 0.18.0.0
336
+ version: 0.18.0.1
337
337
  - !ruby/object:Gem::Dependency
338
338
  name: elasticgraph-elasticsearch
339
339
  requirement: !ruby/object:Gem::Requirement
340
340
  requirements:
341
341
  - - '='
342
342
  - !ruby/object:Gem::Version
343
- version: 0.18.0.0
343
+ version: 0.18.0.1
344
344
  type: :development
345
345
  prerelease: false
346
346
  version_requirements: !ruby/object:Gem::Requirement
347
347
  requirements:
348
348
  - - '='
349
349
  - !ruby/object:Gem::Version
350
- version: 0.18.0.0
350
+ version: 0.18.0.1
351
351
  - !ruby/object:Gem::Dependency
352
352
  name: elasticgraph-opensearch
353
353
  requirement: !ruby/object:Gem::Requirement
354
354
  requirements:
355
355
  - - '='
356
356
  - !ruby/object:Gem::Version
357
- version: 0.18.0.0
357
+ version: 0.18.0.1
358
358
  type: :development
359
359
  prerelease: false
360
360
  version_requirements: !ruby/object:Gem::Requirement
361
361
  requirements:
362
362
  - - '='
363
363
  - !ruby/object:Gem::Version
364
- version: 0.18.0.0
364
+ version: 0.18.0.1
365
365
  - !ruby/object:Gem::Dependency
366
366
  name: elasticgraph-indexer
367
367
  requirement: !ruby/object:Gem::Requirement
368
368
  requirements:
369
369
  - - '='
370
370
  - !ruby/object:Gem::Version
371
- version: 0.18.0.0
371
+ version: 0.18.0.1
372
372
  type: :development
373
373
  prerelease: false
374
374
  version_requirements: !ruby/object:Gem::Requirement
375
375
  requirements:
376
376
  - - '='
377
377
  - !ruby/object:Gem::Version
378
- version: 0.18.0.0
378
+ version: 0.18.0.1
379
379
  - !ruby/object:Gem::Dependency
380
380
  name: elasticgraph-schema_definition
381
381
  requirement: !ruby/object:Gem::Requirement
382
382
  requirements:
383
383
  - - '='
384
384
  - !ruby/object:Gem::Version
385
- version: 0.18.0.0
385
+ version: 0.18.0.1
386
386
  type: :development
387
387
  prerelease: false
388
388
  version_requirements: !ruby/object:Gem::Requirement
389
389
  requirements:
390
390
  - - '='
391
391
  - !ruby/object:Gem::Version
392
- version: 0.18.0.0
392
+ version: 0.18.0.1
393
393
  description:
394
394
  email:
395
395
  - myron@squareup.com