Class: ElasticsearchRecord::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/elasticsearch_record/query.rb

Direct Known Subclasses

Arel::Collectors::ElasticsearchQuery

Constant Summary collapse

STATUS_VALID =

STATUS CONSTANTS

:valid
STATUS_FAILED =
:failed
TYPE_UNDEFINED =

-- UNDEFINED TYPE ------------------------------------------------------------------------------------------------

:undefined
TYPE_COUNT =

-- QUERY TYPES ---------------------------------------------------------------------------------------------------

:count
TYPE_SEARCH =
:search
TYPE_MSEARCH =
:msearch
TYPE_SQL =
:sql
TYPE_ESQL =

PLEASE NOTE: ES|QL requires Elasticsearch >= 8.11 (the esql API namespace does not exist before that)

:esql
TYPE_CREATE =

-- DOCUMENT TYPES ------------------------------------------------------------------------------------------------

:create
TYPE_UPDATE =
:update
TYPE_UPDATE_BY_QUERY =
:update_by_query
TYPE_DELETE =
:delete
TYPE_DELETE_BY_QUERY =
:delete_by_query
TYPE_INDEX_CREATE =

-- INDEX TYPES ---------------------------------------------------------------------------------------------------

:index_create
TYPE_INDEX_CLONE =
:index_clone
TYPE_INDEX_UPDATE_MAPPING =

INDEX update is not implemented by Elasticsearch

  • this is handled through individual updates of mappings, settings & aliases. INDEX delete is handled directly as API-call
:index_update_mapping
TYPE_INDEX_UPDATE_SETTING =
:index_update_setting
TYPE_INDEX_UPDATE_ALIAS =
:index_update_alias
TYPE_INDEX_DELETE_ALIAS =
:index_delete_alias
TYPES =

includes valid types only

[
  # -- QUERY TYPES
  TYPE_COUNT, TYPE_SEARCH, TYPE_MSEARCH, TYPE_SQL, TYPE_ESQL,
  # -- DOCUMENT TYPES
  TYPE_CREATE, TYPE_UPDATE, TYPE_UPDATE_BY_QUERY, TYPE_DELETE, TYPE_DELETE_BY_QUERY,

  # -- INDEX TYPES
  TYPE_INDEX_CREATE, TYPE_INDEX_CLONE,
  TYPE_INDEX_UPDATE_MAPPING, TYPE_INDEX_UPDATE_SETTING, TYPE_INDEX_UPDATE_ALIAS,
  TYPE_INDEX_DELETE_ALIAS
].freeze
READ_TYPES =

includes reading types only

[
  TYPE_COUNT, TYPE_SEARCH, TYPE_MSEARCH, TYPE_SQL, TYPE_ESQL
].freeze
FAILED_BODIES =

defines a body to be executed if the query fails - (none) acts like the SQL-query "where('1=0')"

{
  TYPE_SEARCH => { size: 0, query: { bool: { filter: [{ term: { _id: '_' } }] } } },
  TYPE_COUNT => { query: { bool: { filter: [{ term: { _id: '_' } }] } } }
}.freeze
GATES_MAP =

defines special api gates to be used per type. if no special type is defined, it simply uses [:core,self.type]

Returns:

{
  TYPE_SQL => 'sql.query',
  TYPE_ESQL => 'esql.query',
  TYPE_INDEX_CREATE => 'indices.create',
  TYPE_INDEX_CLONE => 'indices.clone',
  TYPE_INDEX_UPDATE_MAPPING => 'indices.put_mapping',
  TYPE_INDEX_UPDATE_SETTING => 'indices.put_settings',
  TYPE_INDEX_UPDATE_ALIAS => 'indices.put_alias',
  TYPE_INDEX_DELETE_ALIAS => 'indices.delete_alias'
}.freeze
COLUMNS_NONE =

defines a projection marker that forces a query to return no _source fields at all. metadata fields ('_id', '_score', ...) are not part of the _source - they are always returned on the document level and therefore stay accessible.

this is the only way to clear the columns that visit_Arel_Nodes_SelectCore claims for every relation - a configure can only reach the query-body, never the columns.

HINT: only evaluated as the first projection - combining it with other fields (e.g. select(COLUMNS_NONE, :name)) silently discards them.

see @ ElasticsearchRecord::Relation::ResultMethods#meta_only! see @ Arel::Visitors::ElasticsearchQuery#visit_Selects

'!'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(index: nil, type: TYPE_UNDEFINED, status: STATUS_VALID, body: nil, refresh: nil, timeout: nil, arguments: {}, columns: []) ⇒ Query

Returns a new instance of Query.



123
124
125
126
127
128
129
130
131
132
# File 'lib/elasticsearch_record/query.rb', line 123

def initialize(index: nil, type: TYPE_UNDEFINED, status: STATUS_VALID, body: nil, refresh: nil, timeout: nil, arguments: {}, columns: [])
  @index = index
  @type = type
  @status = status
  @refresh = refresh
  @timeout = timeout
  @body = body
  @arguments = arguments
  @columns = columns
end

Instance Attribute Details

#argumentsObject (readonly)

defines the query arguments to be passed to the API



117
118
119
# File 'lib/elasticsearch_record/query.rb', line 117

def arguments
  @arguments
end

#ArrayObject

defines the columns to assign from the query



121
# File 'lib/elasticsearch_record/query.rb', line 121

attr_reader :columns

#BooleanObject

defines if the affected shards gets refreshed to make this operation visible to search



109
# File 'lib/elasticsearch_record/query.rb', line 109

attr_reader :refresh

#columnsObject (readonly)

defines the columns to assign from the query



121
122
123
# File 'lib/elasticsearch_record/query.rb', line 121

def columns
  @columns
end

#HashObject

defines the query arguments to be passed to the API



117
# File 'lib/elasticsearch_record/query.rb', line 117

attr_reader :arguments

#indexObject (readonly)

defines the index the query should be executed on



95
96
97
# File 'lib/elasticsearch_record/query.rb', line 95

def index
  @index
end

#Integer|StringObject

defines the query timeout



113
# File 'lib/elasticsearch_record/query.rb', line 113

attr_reader :timeout

#refreshObject (readonly)

defines if the affected shards gets refreshed to make this operation visible to search



109
110
111
# File 'lib/elasticsearch_record/query.rb', line 109

def refresh
  @refresh
end

#statusObject (readonly)

defines the query status.

See Also:

  • STATUSES


105
106
107
# File 'lib/elasticsearch_record/query.rb', line 105

def status
  @status
end

#StringObject

defines the index the query should be executed on



95
# File 'lib/elasticsearch_record/query.rb', line 95

attr_reader :index

#SymbolObject

defines the query status.

See Also:

  • STATUSES


100
# File 'lib/elasticsearch_record/query.rb', line 100

attr_reader :type

#timeoutObject (readonly)

defines the query timeout



113
114
115
# File 'lib/elasticsearch_record/query.rb', line 113

def timeout
  @timeout
end

#typeObject (readonly)

defines the query type.

See Also:



100
101
102
# File 'lib/elasticsearch_record/query.rb', line 100

def type
  @type
end

Instance Method Details

#bodyHash?

returns the query body - depends on the status! failed queried will return the related FAILED_BODIES or {} as fallback

Returns:



173
174
175
176
177
# File 'lib/elasticsearch_record/query.rb', line 173

def body
  return (FAILED_BODIES[self.type].presence || {}) if failed?

  @body
end

#failed!ElasticsearchRecord::Query

sets the failed status for this query. returns self



137
138
139
140
141
# File 'lib/elasticsearch_record/query.rb', line 137

def failed!
  @status = STATUS_FAILED

  self
end

#failed?Boolean

returns true, if the query failed

Returns:



145
146
147
# File 'lib/elasticsearch_record/query.rb', line 145

def failed?
  self.status == STATUS_FAILED
end

#gateSymbol, String

returns the API gate to be called to execute the query. each query type needs a different endpoint.

Returns:

See Also:

  • Elasticsearch::API


160
161
162
# File 'lib/elasticsearch_record/query.rb', line 160

def gate
  GATES_MAP[self.type].presence || self.type
end

#query_argumentsHash Also known as: to_query

builds the final query arguments. Depends on the query status, index, body & refresh attributes. Also used possible PRE-defined arguments to be merged with those mentioned attributes.

Returns:



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/elasticsearch_record/query.rb', line 183

def query_arguments
  args = @arguments.deep_dup

  # set index, if present
  args[:index] = self.index if self.index.present?

  # set body, if present
  args[:body] = self.body if self.body.present?

  # set refresh, if defined (also includes false value)
  args[:refresh] = self.refresh unless self.refresh.nil?

  # set timeout, if present
  args[:timeout] = self.timeout if self.timeout.present?

  args
end

#valid?Boolean

returns true, if the query is valid (e.g. index & type defined)

Returns:



151
152
153
154
# File 'lib/elasticsearch_record/query.rb', line 151

def valid?
  # type mus be valid + index must be present (not required for SQL)
  TYPES.include?(self.type) #&& (index.present? || self.type == TYPE_SQL)
end

#write?Boolean

returns true if this is a write query

Returns:



166
167
168
# File 'lib/elasticsearch_record/query.rb', line 166

def write?
  !READ_TYPES.include?(self.type)
end