Module: ElasticMapper::Search::ClassMethods

Defined in:
lib/elastic_mapper/search.rb

Instance Method Summary collapse

Instance Method Details

#search(query, opts = {}, query_sanitized = false) ⇒ ActiveModel|Array

Search on a model’s mapping. Either a String, or a hash can be provided for the query. If a string is provided, a search will be performed using the ElasticSearch query DSL. If a hash is provided, it will be passed directly to stretcher.

Parameters:

  • query (String|Hash)

    the search query.

  • opts (Hash) (defaults to: {})

    query options.

Returns:

  • (ActiveModel|Array)

    the search results.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/elastic_mapper/search.rb', line 21

def search(query, opts = {}, query_sanitized = false)

  opts = {
    sort: { _score: 'desc' },
    # from and size, are used to paginate
    # in ElasticSearch
    from: 0,
    size: 20
  }.update(opts)

  # Convert string query to search DSL.
  query_hash = if query.is_a?(String)
    query_string_to_hash(query)
  else
    query
  end

  # Perform the query in a try/catch block, attempt
  # to sanitize the query if it fails.
  begin
    res = ElasticMapper.index.type(
      self.instance_variable_get(:@_mapping_name)
    ).search(
      { query: query_hash }.merge(opts)
    )
  rescue Stretcher::RequestError => e
    # the first time a query fails, attempt to
    # sanitize the query and retry the search.
    # This gives users the power of the Lucene DSL
    # while protecting them from badly formed queries.
    if query_sanitized
      raise e
    else
      return search(sanitize_query(query), opts, true)
    end
  end

  # if a search is being performed across multiple
  # models, we must include the type along with id:
  documents = if self.class.name =~ /MultiSearch/
    ids = res.results.map do |obj|
      {
        id: "#{obj._type}_#{obj.id}",
        obj_id: obj.id,
        type: obj._type
      }
    end

    ordered_results_multi(ids)
  else
    ordered_results(res.results.map(&:id))
  end

  Hashie::Mash.new({
    documents: documents,
    from: opts[:from],
    total: res.total
  })
end