elasticgraph-graphql 0.18.0.0 → 0.18.0.1

Sign up to get free protection for your applications and to get access to all the features.
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