Integrations / Frameworks / Rails / Replicas & Multiple Indices

Replicas & Multiple Indices

Replicas

Algolia pre-sorts records based on the ranking formula and custom ranking, ensuring that matching records are already in the correct order when searching. If you want to offer multiple sorting strategies, you need to add replicas.

You can define replica indices using the add_replica method. Use inherit: true on the replica block if you want to inherit settings from the primary index.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Book < ActiveRecord::Base
  attr_protected

  include AlgoliaSearch

  algoliasearch per_environment: true do
    searchableAttributes [:name, :author, :editor]

    # define a replica index to search by `author` only
    add_replica 'Book_by_author', per_environment: true do
      searchableAttributes [:author]
    end

    # define a replica index with custom ordering but same settings than the main block
    add_replica 'Book_custom_order', inherit: true, per_environment: true do
      customRanking ['asc(rank)']
    end
  end

end

Share a single index

It can make sense to share an index between several models.

If you add multiple models to the same index, you must ensure you don’t have conflicting objectIDs. By default, the objectID is the primary key of the model. One solution is to prepend the key with the model class name.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Student < ActiveRecord::Base
  attr_protected

  include AlgoliaSearch

  algoliasearch index_name: 'people', id: :algolia_id do
    # [...]
  end

  private
  def algolia_id
    "student_#{id}" # ensure the teacher & student IDs are not conflicting
  end
end

class Teacher < ActiveRecord::Base
  attr_protected

  include AlgoliaSearch

  algoliasearch index_name: 'people', id: :algolia_id do
    # [...]
  end

  private
  def algolia_id
    "teacher_#{id}" # ensure the teacher & student IDs are not conflicting
  end
end

If you target a single index from several models, you must use MyModel.reindex! instead of MyModel.reindex. The reindex method uses a temporary index to perform an atomic reindexing. Using it with several models would cause the resulting index to only contain records for the current model.

Target multiple indices

You can index a record in several indices using the add_index method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Book < ActiveRecord::Base
  attr_protected

  include AlgoliaSearch

  PUBLIC_INDEX_NAME  = "Book_#{Rails.env}"
  SECURED_INDEX_NAME = "SecuredBook_#{Rails.env}"

  # store all books in index 'SECURED_INDEX_NAME'
  algoliasearch index_name: SECURED_INDEX_NAME do
    searchableAttributes [:name, :author]
    # convert security to tags
    tags do
      [released ? 'public' : 'private', premium ? 'premium' : 'standard']
    end

    # store all 'public' (released and not premium) books in index 'PUBLIC_INDEX_NAME'
    add_index PUBLIC_INDEX_NAME, if: :public? do
      searchableAttributes [:name, :author]
    end
  end

  private
  def public?
    released && !premium
  end

end
Did you find this page helpful?