Class: Scrivito::ObjSearchEnumerator

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/scrivito/obj_search_enumerator.rb

Overview

Provides an enumerator for iterating over obj search results and retrieving obj instances. This is done using the Enumerable mixin, which provides methods such as map, select or take.

This enumerator is lazy. If for example you are looking for Objs with the ObjClass “Publication”, and there are 93 objs in total, than enum.take(10) will fetch the first 10 objs only, ignoring the other 83 objs. This also means, that iterating multiple times over this enumerator causes the search results and objs to be fetched again. If you want to get all objs at once, use enum.to_a.

To start searching use one of the Obj methods that returns an ObjSearchEnumerator. The preferred way is to start with Obj.where.

Currently available fields and their values

:*

Searches all fields. This is only possible with the operators contais or starts_with.

:id

Id of an Obj. This is a string field.

:_path

Path of an Obj. This is a string field.

:_name

Name of an Obj. This is a string field.

:title

Title of an Obj. This is a string field.

:body

Body of an Obj. This is an html field. Thus, only the contains and contains_prefix operators can be applied to this field.

:_obj_class

ObjClass of an Obj. This is a string field.

:_permalink

Permalink of an Obj. This is a string field.

:_last_changed

Date of last change of an Obj.

every :custom_attribute

Custom attribute of an Obj. Note that depending on the attribute type (e.g. an html field), some operators can not be applied.

All values are stored as strings.

Date values are stored in the format YYYYMMDDHHMMSS in UTC. For example, 2000-01-01 00:00:00 UTC is stored as “20000101000000”. This is relevant for string comparisons using the is_less_than and is_greater_than operators.

Currently available operators

For :contains and :contains_prefix, the examples are based on the following field value: “Behind every cloud is another cloud.”

:contains

Searches for one or more whole words. Each word needs to be present.

Example subquery values:

✔ “behind cloud” (case insensitive)

✘ “behi clo” (not whole words)

✘ “behind everything” (second word does not match)

:contains_prefix

Searches for one prefix. A whole word is also a prefix.

Example subquery values:

✔ “Clou” (case insensitive)

✔ “Every” (case insensitive)

For :equals and :starts_with, the examples are based on the following field value: “Some content.”

:equals

The field value needs to be identical to the value of this subquery.

Only applicable to string, enum, multienum and date fields.

Example subquery values:

✔ “Some content.” (exact value)

✘ “Some” (not exact value)

:starts_with

The field value needs to start exactly with the value of this subquery.

Only applicable to string, enum, multienum and date fields.

Example subquery values:

✔ “Som” (prefix of the value)

✘ “som” (incorrect case of prefix)

✘ “content” (not prefix of the whole value)

For :is_less_than and :is_greater_than, the examples are based on the following field value (date string): “20000101000000”

:is_less_than

Matches if the field string value is less than the subquery string value.

Only applicable to string, enum, multienum and date fields.

Example subquery values:

✔ “19991231235959” (is less than “20000101000000”)

✘ “20000101000000” (equal, not less than)

:is_greater_than

Matches if the field string value is greater than the subquery string value.

Only applicable to string, enum, multienum and date fields.

Example subquery values:

✔ “20000101000001” (is greater than “20000101000000”)

✘ “20000101000000” (equal, not greater than)

Chainable methods collapse

Instance Method Summary collapse

Instance Method Details

#and(field, operator, value, boost = nil) ⇒ ObjSearchEnumerator

Adds this additional AND subquery to this Scrivito::ObjSearchEnumerator.

Compares the field(s) with the value(s) using the operator of this subquery. All objs to which this criterion applies remain in the result set.

Parameters:

  • field (Symbol, String, Array<Symbol, String>)

    Name(s) of the field(s) to be searched. For arrays, the subquery matches, if one or more of these fields meet this criterion.

  • operator (Symbol, String)

    See “Currently available operators” at the top.

  • value (String, Array<String>)

    The value(s) with which the field value(s) are compared using the operator of this subquery. For arrays, the subquery matches, if the condition is met for one or more of the array elements.

  • boost (Hash) (defaults to: nil)

    A hash where the keys are field names and their values are boosting factors. Boosting factors must be in the range from 1 to 10. Boosting can only be applied to subqueries in which the contains or contains_prefix operator is used.

Returns:



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/scrivito/obj_search_enumerator.rb', line 136

def and(field, operator, value, boost = nil)
  real_operator = operator_mapping(operator)
  subquery = {:field => field, :operator => real_operator, :value => convert_value(value)}
  if boost.present?
    valid_boost_operators = [:contains, :contains_prefix]
    if valid_boost_operators.include?(operator.to_sym)
      subquery[:boost] = boost
    else
      raise "Boost is not allowed with operator '#{operator}'. " +
          "Valid operators are: #{valid_boost_operators.join(', ')}"
    end
  end
  @size = nil
  @query = (query || []) + [subquery]

  self
end

#and_not(field, operator, value) ⇒ ObjSearchEnumerator

Adds this additional negated AND subquery to this Scrivito::ObjSearchEnumerator.

Compares the field(s) with the value(s) using the negated operator of this subquery. All objs to which this criterion applies are removed from the result set.

Parameters:

  • field (Symbol, String, Array<Symbol, String>)

    Name(s) of the field(s) to be searched. For arrays, the subquery matches, if one or more of these fields meet this criterion.

  • operator (Symbol, String)

    Only applicable to subqueries in which the equals, starts_with, is_greater_than and is_less_than operator is used (See “Currently available operators” at the top).

  • value (String, Array<String>)

    The value(s) with which the field value(s) are compared using the operator of this subquery. For arrays, the subquery matches, if the condition is met for one or more of the array elements.

Returns:



168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/scrivito/obj_search_enumerator.rb', line 168

def and_not(field, operator, value)
  real_operator = operator_mapping(operator)
  valid_negated_operators = [:equals, :starts_with, :is_greater_than, :is_less_than]
  unless valid_negated_operators.include?(operator.to_sym)
    raise "Negating operator '#{operator}' is not valid."
  end
  subquery = {:field => field, :operator => real_operator, :value => convert_value(value),
      :negate => true}
  @size = nil
  @query = (query || []) + [subquery]

  self
end

#batch_size(size) ⇒ ObjSearchEnumerator

Number of search results to be returned by each of the internal search requests. The default is 10. The server may limit a large batch size to a reasonable value.

Parameters:

  • size (Integer)

    A value in the range from 1 to 100.

Returns:



208
209
210
211
212
# File 'lib/scrivito/obj_search_enumerator.rb', line 208

def batch_size(size)
  options[:size] = size

  self
end

#each {|Obj| ... }

This method returns an undefined value.

Iterates over the search result, yielding Obj.

Yields:



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/scrivito/obj_search_enumerator.rb', line 238

def each
  offset = options[:offset] || 0
  current_batch, total = fetch_next_batch(offset)
  loop do
    if current_batch.size == 0
      if offset < total
        current_batch, total = fetch_next_batch(offset)
      else
        raise StopIteration
      end
    end

    offset += 1
    hit = current_batch.shift
    yield hit
  end
end

#load_batchObject

load a single batch of search results from the backend. returns an array of Objs. will usually return ‘batch_size` results if available, but may occasionally return fewer than `batch_size` results (due to rate limit, for example).



280
281
282
283
284
# File 'lib/scrivito/obj_search_enumerator.rb', line 280

def load_batch
  next_batch = fetch_next_batch(options[:offset] || 0)

  next_batch.first
end

#offset(amount) ⇒ ObjSearchEnumerator

Omits the first amount number of Objs from the results. The default is 0.

Parameters:

  • amount (Integer)

Returns:



219
220
221
222
223
224
# File 'lib/scrivito/obj_search_enumerator.rb', line 219

def offset(amount)
  options[:offset] ||= 0
  options[:offset] += amount

  self
end

#order(field_name) ⇒ ObjSearchEnumerator

Orders the results by field_name.

Parameters:

  • field_name (Symbol, String)

    This parameter determines by which field the hits are sorted (e.g. :_path).

Returns:



186
187
188
189
190
# File 'lib/scrivito/obj_search_enumerator.rb', line 186

def order(field_name)
  options[:sort_by] = field_name

  self
end

#reverse_orderObjSearchEnumerator

Reverses the order of the results. Requires #order to be specified before.

Returns:



195
196
197
198
199
200
201
# File 'lib/scrivito/obj_search_enumerator.rb', line 195

def reverse_order
  options[:sort_by].present? or raise "A search order has to be specified"\
      " before reverse_order can be applied."
  @reverse_order = !@reverse_order

  self
end

#sizeInteger Also known as: length, count

The total number of hits.

Returns:

  • (Integer)


259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/scrivito/obj_search_enumerator.rb', line 259

def size
  return @size if @size

  size_query = {
    query: query,
    size: 0
  }
  if @include_deleted
    size_query[:options] = {
      include_deleted: true
    }
  end

  @size ||= CmsBackend.instance.search_objs(workspace, size_query)['total'].to_i
end