Module: Dynomite::Item::Query::Params::Helpers

Included in:
Dynomite::Item::Query::Params, Base, Function::Base
Defined in:
lib/dynomite/item/query/params/helpers.rb

Instance Method Summary collapse

Instance Method Details

#all_where_field_namesObject



72
73
74
# File 'lib/dynomite/item/query/params/helpers.rb', line 72

def all_where_field_names
  all_where_fields.map { |k| k.split('.').first }
end

#all_where_fieldsObject

full field names with operator



68
69
70
# File 'lib/dynomite/item/query/params/helpers.rb', line 68

def all_where_fields
  query[:where].map(&:keys).flatten.map(&:to_s)
end

#disable_index_for_any_or?Boolean

Always run scan when any or in chain For dynomite, ‘or` expressions will always result in a scan operation. This is because `key_condition_expression` does not support OR expressions. Nor does it make sense to use query with an index in the first pass with `key_condition_expression` and use `filter_expression` in the second pass. The `key_condition_expression` and `filter_expression` are AND with each other, so it would not be possible to do an OR without a scan.

Returns:

  • (Boolean)


38
39
40
41
42
# File 'lib/dynomite/item/query/params/helpers.rb', line 38

def disable_index_for_any_or?
  disable = query[:where].any? { |where_group| where_group.or? }
  logger.info "Disabling index since an or was used" if disable && ENV['DYNOMITE_DEBUG']
  disable
end

#disable_index_for_consistent_read?(index) ⇒ Boolean

Returns:

  • (Boolean)


53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/dynomite/item/query/params/helpers.rb', line 53

def disable_index_for_consistent_read?(index)
  if query.key?(:consistent_read)
    if index.nil?
      true # must use scan for consistent read
    elsif index.primary?
      false # can use index for consistent ready for the primary key index only
    else
      true # must use scan for GSI indexes
    end
  else
    false
  end
end

#disable_index_for_not?(index) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
47
48
49
50
51
# File 'lib/dynomite/item/query/params/helpers.rb', line 44

def disable_index_for_not?(index)
  disable = query[:where].any? do |where_group|
    x = where_group.fields & index.fields
    !x.empty? && where_group.not?
  end
  logger.info "Disabling index since a not was used for the index" if disable && ENV['DYNOMITE_DEBUG']
  disable
end

#normalize_expression_path(path) ⇒ Object



76
77
78
79
80
# File 'lib/dynomite/item/query/params/helpers.rb', line 76

def normalize_expression_path(path)
  path.split('.').map do |field|
    field.starts_with?('#') ? field : field.prepend('#')
  end.join('.')
end

#normalize_project_expression(args) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/dynomite/item/query/params/helpers.rb', line 82

def normalize_project_expression(args)
  project_expression = []
  args.map do |element|
    if element.is_a?(String)
      project_expression += element.split(',').map(&:strip)
    else
      project_expression << element.to_s
    end
  end
  project_expression
end

#queryObject



13
14
15
# File 'lib/dynomite/item/query/params/helpers.rb', line 13

def query
  @relation.query
end

#scan_required?(index) ⇒ Boolean

Certain queries require a scan, so we can’t use the key condition

Returns:

  • (Boolean)


18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/dynomite/item/query/params/helpers.rb', line 18

def scan_required?(index)
  return true if index.nil? # first check
  return true if query[:force_scan]
  return true if disable_index_for_any_or?
  return true if disable_index_for_not?(index)
  return true if disable_index_for_consistent_read?(index)

  all_where_fields.find do |full_field|
    field, operator = full_field.split('.')
    index.fields.include?(field) && !operator.nil?
  end
end

#with_where_groupsObject

Important to reset relation index for each relation chain so that attribute name references are correct. Using ‘with_where_groups` when interating ensures index is reset.



6
7
8
9
10
11
# File 'lib/dynomite/item/query/params/helpers.rb', line 6

def with_where_groups
  @relation.index = 0
  @relation.query[:where].each do |where_group|
    yield(where_group)
  end
end