Search
Front-end search
Traditional search implementations tend to have search logic and functionality on the back end. This made sense when the search experience consisted of a user entering a search query, executing that search, and then being redirected to a search result page.
Implementing search on the back end is no longer necessary. In fact, in most cases it is harmful to performance because of added network and processing latency. We highly recommend the usage of our InstantSearch libraries issuing all search requests directly from the end user’s browser, mobile device, or client. It will reduce the overall search latency while offloading your servers at the same time.
To create real-time search experience, you can use our InstantSearch libraries.
Built on top of the JavaScript client, InstantSearch is a set of components to help you build your search. It comes in different flavors for all popular JavaScript frameworks:
Backend Search
We recommend building a frontend search experience to perform queries directly from the end user browser without going through your server; there are, however, some cases where you want to search in the back end.
A search returns ORM-compliant Rails model objects. Your back end will search through Algolia but then load models directly from the database.
1
2
hits = Contact.search("jon doe")
p hits
The search method will accept any search parameters as second argument.
1
2
# dynamical search parameters
p Contact.search('jon doe', { hitsPerPage: 5, page: 2 })
Some search parameters can be set in the index settings. This is recommended if you find yourself always passing the same search parameters.
1
2
3
4
5
6
7
8
9
10
class Contact < ActiveRecord::Base
include AlgoliaSearch
algoliasearch do
# default search parameters stored in the index settings
minWordSizefor1Typo 4
minWordSizefor2Typos 8
hitsPerPage 42
end
end
Each ORM object returned is enriched with highlight_result
attribute from Algolia’s raw response.
See the highlighting and snippeting documentation for more information.
1
hits[0].highlight_result['first_name']['value']
Raw search
If you want to retrieve something from the original raw Algolia response, you can access it from the response array.
1
2
3
hits = Contact.search("jon doe")
p hits.raw_answer['nbHits']
p hits.raw_answer['nbPages']
If you don’t need models, you can avoid loading objects from the database and get the Algolia raw json response directly.
1
2
3
4
json_answer = Contact.raw_search("jon doe")
p json_answer
p json_answer['hits']
p json_answer['facets']
Searching in a specific index
In some cases, you may need to specify the index name when searching. It typically happens when you use the
add_index
method in your model configuration. In this case, you can pass the index
key
in the second argument, along with search parameters.
1
2
Book.search 'foo bar', index: 'Book_by_editor'
Book.raw_search 'foo bar', index: 'Book_by_editor'
The replica
key is also available. Internally, it’s the same as index
but it’s more explicit.
1
2
Book.search 'foo bar', replica: 'Book_by_editor'
Book.raw_search 'foo bar', replica: 'Book_by_editor'
Back end Pagination
Even if we highly recommend to perform all search (and therefore pagination) operations from your front end using JavaScript, we support both will_paginate and kaminari as pagination back ends.
To use :will_paginate
, specify the :pagination_backend
in your global configuration:
1
2
3
4
5
AlgoliaSearch.configuration = {
application_id: 'YourApplicationID',
api_key: 'YourAdminAPIKey',
pagination_backend: :will_paginate
}
Then, as long as you use the search
method, the returning results will be a paginated set:
1
2
3
4
5
6
7
8
9
# in your controller
@results = MyModel.search('foo', hitsPerPage: 10)
# in your views
# if using will_paginate
<%= will_paginate @results %>
# if using kaminari
<%= paginate @results %>
Faceting
Facets can be retrieved calling the extra facets
method of the search array response.
To be able to retrieve facets, the necessary attributes must be defined as attributesForFaceting
.
Read more in the index settings section.
1
2
3
4
5
hits = Contact.search('jon doe', { facets: '*' })
p hits # ORM-compliant array of objects
p hits.facets # extra method added to retrieve facets
p hits.facets['company'] # facet values+count of facet 'company'
p hits.facets['zip_code'] # facet values+count of facet 'zip_code'
1
2
raw_json = Contact.raw_search('jon doe', { facets: '*' })
p raw_json['facets']
Search for facet values
Sometimes you have so many different values for your facets that you wish you could search through them.
Good news, Algolia can search for facet values, as long as you qualified the searchableAttribute
as searchable
](/doc/guides/managing-results/refine-results/faceting/#declaring-a-searchable-attribute-for-faceting).
1
Product.search_for_facet_values('category', 'Headphones') # Array of {value, highlighted, count}
This method can also take any parameter a query can take. This will adjust the search to only hits which would have matched the query.
1
2
3
4
5
# Only sends back the categories containing red Apple products (and only counts those)
Product.search_for_facet_values('category', 'phone', {
query: 'red',
filters: 'brand:Apple'
}) # Array of phone categories linked to red Apple products