Class: Mebla::Search

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/mebla/search.rb

Overview

Handles all searching functions and chains search to define filters, sorting or facets.

This example searches posts by tags, sorts and filters the results

criteria = Post.search.terms(:tags, [‘ruby’, ‘rails’]).ascending(:publish_date).only(:author => [‘cousine’])

This will search the index for posts tagged ‘ruby’ or ‘rails’, arrange the results ascendingly according to their publish dates, and filter the results by the author named ‘cousine’.

The search won’t be executed unless we try accessing the results collection

results = criteria.hits

Or directly iterate the collection

criteria.each do |result|

...

end

Mebla supports multiple methods of searching

You can either search by direct Lucene query

Mebla.search(“query”)

Or by term

Mebla.search.term(:field, “term”)

Or by terms

Mebla.search.terms(:field, [“term 1”, “term 2”, …])

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query_string = "", type_names = []) ⇒ Search

Creates a new Search object

Parameters:

  • query_string (String) (defaults to: "")

    optional search query

  • type_names (String, Symbol, Array) (defaults to: [])

    a string, symbol or array representing the models to be searcheds



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/mebla/search.rb', line 42

def initialize(query_string = "", type_names = [])
  # Convert type names from string or symbol to array
  type_names = case true
    when type_names.is_a?(Symbol), type_names.is_a?(String)
      [type_names]      
    when type_names.is_a?(Array) && !type_names.empty?
      type_names.collect{|name| name.to_s}
    else
      []
    end
    
    @slingshot_search = Slingshot::Search::Search.new(Mebla.context.slingshot_index_name, {})
    # Add a type filter to return only certain types
    unless type_names.empty?
      only(:_type => type_names)
    end
    
    unless query_string.blank?
      query(query_string)
    end
end

Instance Attribute Details

#resultsObject (readonly)

Returns the value of attribute results.



37
38
39
# File 'lib/mebla/search.rb', line 37

def results
  @results
end

#slingshot_searchObject (readonly)

Returns the value of attribute slingshot_search.



37
38
39
# File 'lib/mebla/search.rb', line 37

def slingshot_search
  @slingshot_search
end

Instance Method Details

#ascending(field) ⇒ Mebla::Search Also known as: asc

Sorts results ascendingly

Parameters:

  • field (String, Symbol)

    to sort by

Returns:



115
116
117
118
119
# File 'lib/mebla/search.rb', line 115

def ascending(field)
  @slingshot_search = @slingshot_search.sort
  @slingshot_search.instance_variable_get(:@sort).send(field.to_sym, 'asc')
  self
end

#descending(field) ⇒ Mebla::Search Also known as: desc

Sorts results descendingly

Parameters:

  • field (String, Symbol)

    to sort by

Returns:



124
125
126
127
128
# File 'lib/mebla/search.rb', line 124

def descending(field)
  @slingshot_search = @slingshot_search.sort
  @slingshot_search.instance_variable_get(:@sort).send(field.to_sym, 'desc')
  self
end

#each(&block) ⇒ Object

Iterates over the results collection



233
234
235
# File 'lib/mebla/search.rb', line 233

def each(&block)
  hits.each(&block)
end

#entriesArray

Returns the internal results list

Returns:

  • (Array)


203
204
205
# File 'lib/mebla/search.rb', line 203

def entries
  hits.entries
end

#facet(name, field, options = {}) ⇒ Mebla::Search

Note:

check / elasticsearch’s facet reference for more information

Creates a new facet for the search

Defining a global facet named “tags”

Post.search(“*”).facet(“tags”, :tag, :global => true)

Parameters:

  • name (String)

    of the facet

  • field (String, Symbol)

    to create a facet for

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

Returns:



141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/mebla/search.rb', line 141

def facet(name, field, options={})
  # Get the hash
  facet_hash = @slingshot_search.instance_variable_get(:@facets)
  # Create a new Facet
  facet_obj = Slingshot::Search::Facet.new(name, options)
  facet_obj.terms(field)
  # Initialize the hash if its nil
  if facet_hash.nil?
    @slingshot_search.instance_variable_set(:@facets, {})
  end
  # Add the facet to the hash
  @slingshot_search.instance_variable_get(:@facets).update facet_obj.to_hash        
  self
end

#facetsHash

Retrieves the facets

Reading a facet named ‘tags’

facets = Post.search(“*”).facet(“tags”, :tag) facets.each do |term|

puts "#{term['term']} - #{term['count']}"

end

Returns:

  • (Hash)


228
229
230
# File 'lib/mebla/search.rb', line 228

def facets
  hits.facets
end

#from(value) ⇒ Mebla::Search

Sets the starting offset for the query

Parameters:

  • value (Integer)

Returns:



182
183
184
185
# File 'lib/mebla/search.rb', line 182

def from(value)
  @slingshot_search = @slingshot_search.from(value)
  self
end

#hitsMebla::ResultSet

Performs the search and returns the results

Returns:



189
190
191
192
193
194
195
196
197
198
199
# File 'lib/mebla/search.rb', line 189

def hits
  return @results if @results
  # Log search query
  Mebla.log("Searching:\n#{@slingshot_search.to_json.to_s}", :debug)
  response = @slingshot_search.perform.json
  Mebla.log("Response:\n#{response.to_json.to_s}", :info)
  @results = Mebla::ResultSet.new(response)
  # Log results statistics
  Mebla.log("Searched for:\n#{@slingshot_search.to_json.to_s}\ngot #{@results.total} documents in #{@results.time} ms", :debug)
  @results
end

#only(*fields) ⇒ Mebla::Search

Filters the results according to the criteria

Get all indexed Posts and filter them by tags and authors

Post.search(“*”).only(:tag => [“ruby”, “rails”], :author => [“cousine”])

Parameters:

  • fields (*Hash)

    hash for each filter

Returns:



163
164
165
166
167
168
169
# File 'lib/mebla/search.rb', line 163

def only(*fields)
  return if fields.empty?
  fields.each do |field|
    @slingshot_search = @slingshot_search.filter(:terms, field)
  end
  self
end

#query(query_string, options = {}) ⇒ Object

Note:

For more information check Lucene’s query syntax

Creates a Lucene query string search criteria

Match Posts with “Test Lucene query” as title

Post.search.query(“Test Lucene query”, :default_field => “title”)

You can also instead

Post.search.query(“title: Test Lucene query”)

Or to search all fields

Post.search.query(“Test Lucene query”)

Parameters:

  • query_string (String)

    search query

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

    to refine the search



106
107
108
109
110
# File 'lib/mebla/search.rb', line 106

def query(query_string, options = {})
  @slingshot_search = @slingshot_search.query
  @slingshot_search.instance_variable_get(:@query).string(query_string, options)
  self
end

#size(value) ⇒ Mebla::Search

Sets the maximum number of hits per query, defaults to 10

Parameters:

  • value (Integer)

Returns:



174
175
176
177
# File 'lib/mebla/search.rb', line 174

def size(value)
  @slingshot_search = @slingshot_search.size(value)
  self
end

#term(field, value) ⇒ Mebla::Search

Creates a term search criteria

Parameters:

  • field (String, Symbol)

    the field to search

  • value (String)

    term to match

Returns:



83
84
85
86
87
# File 'lib/mebla/search.rb', line 83

def term(field, value)
  @slingshot_search = @slingshot_search.query
  @slingshot_search.instance_variable_get(:@query).term(field, value)
  self
end

#terms(field, values, options = {}) ⇒ Mebla::Search

Creates a terms search criteria

Match Posts tagged with either ‘ruby’ or ‘rails’

Post.search.terms(:tags, [‘ruby’, ‘rails’], :minimum_match => 1)

Parameters:

  • field (String, Symbol)

    the field to search

  • values (Array)

    the terms to match

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

    to refine the search

Returns:



73
74
75
76
77
# File 'lib/mebla/search.rb', line 73

def terms(field, values, options = {})      
  @slingshot_search = @slingshot_search.query
  @slingshot_search.instance_variable_get(:@query).terms(field, values, options)
  self
end

#timeFloat

Retrieves the time taken to perform the search in ms

Returns:

  • (Float)


215
216
217
# File 'lib/mebla/search.rb', line 215

def time
  hits.time
end

#totalInteger

Retrieves the total number of hits

Returns:

  • (Integer)


209
210
211
# File 'lib/mebla/search.rb', line 209

def total
  hits.total
end