Framework integration / Symfony / Indexing

Before you begin

Once you have configured what entities you want to index in Algolia, you can send data.

This guide uses this Post entity and the following configuration.

1
2
3
4
5
6
algolia_search:
  indices:
    - name: posts
      class: App\Entity\Post
    - name: comments
      class: App\Entity\Comment

Indexing manually

Using the CLI

Once your indices configuration is ready, you can use the built-in console command to batch import all existing data.

1
2
3
4
5
# Import all indices
php bin/console search:import

# Choose what indices to reindex by passing the index name
php bin/console search:import --indices=posts,comments

Before reindexing everything, you may want to clear the index first, see how to remove data.

Programmatically

To index any entities in your code, you will need to use the SearchService. You need to pass it the ObjectManager associated with your objects and the objects to index. Objects can be a single entity, an array of entities or even an array of different entities as long as they are using the same ObjectManager.

1
2
3
4
5
$searchService->index($entityManager, $post);

$searchService->index($entityManager, $posts);

$searchService->index($entityManager, $postsAndComments);

You have the possibility to pass a third optional argument to the index method, the $requestOptions array or object. You can add any parameter, such as extra headers or the autoGenerateObjectIDIfNotExist parameter.

1
2
3
$searchService->index($entityManager, $anyObject, [
  'autoGenerateObjectIDIfNotExist' => false
]);

The index method, along with all the methods used to manage your data and indexes in the SearchService, is waitable. By chaining the function wait() to your operation, you’re saying explicitly that you want to wait for the engine to finish processing your task before moving on.

1
$searchService->index($entityManager, $anyObject)->wait();

Removing manually

Using the CLI

You may want to completely clear your indices (before reindexing for example), you can use the search:clear command.

1
2
3
4
5
# Clear all indices
php bin/console search:clear

# Choose what indices to clear by passing the index name
php bin/console search:clear --indices=posts,comments

Programmatically

The same way you index data, you can use the remove method to delete entries from the Algolia index.

1
2
3
4
5
$searchService->remove($entityManager, $post);

$searchService->remove($entityManager, $posts);

$searchService->remove($entityManager, $postsAndComments);

Here as well, you can pass $requestOptions:

1
$searchService->remove($entityManager, $anyObject, $requestOptions);

And wait for the engine to process your deletion completely:

1
$searchService->remove($entityManager, $anyObject)->wait();

Indexing automatically using Doctrine events

By default, the bundle listens to the following Doctrine events: postPersist, postUpdate, preRemove. Every time data is inserted, updated, or deleted using Doctrine, your Algolia index will stay in sync.

You can easily modify which events the bundle subscribes to with the doctrineSubscribedEvents configuration key.

You can unsubscribe from all events by passing an empty array. This can become very handy if you are working with a queue (like RabbitMQ) or if you don’t want to call Algolia in your development environment.

1
2
3
4
5
6
7
8
# Only insert new data (no update, no deletion)
algolia_search:
  doctrineSubscribedEvents: ['postPersist']

# Unsubscribe from all events
algolia_search:
  doctrineSubscribedEvents: []

Indexing conditionally

Most of the time, there are some of your items that you don’t want to index. For instance, you may want to only index a post if it’s published.

In your configuration, you can specify when a post should be indexed with the index_if key. Because Algolia relies on the PropertyAccess component you can pass a method name, a class property name or even a nested key in an property array.

The property must evaluate to true to index the entity and false to bypass indexing. If you’re updating an entity using Doctrine and this property evaluates to false, the entity will be removed.

Example with a method or a property

1
2
3
4
5
algolia_search:
  indices:
    - name: posts
      class: App\Entity\Post
      index_if: isPublished

In this case, isPublished could be a method or a class property.

With a method:

1
2
3
4
5
6
7
class Post
{
    public function isPublished()
    {
        return !is_null($this->published_at);
    }
}

With a property:

1
2
3
4
class Post
{
    public $isPublished = true;
}

Example with an array

1
2
3
4
5
algolia_search:
  indices:
    - name: posts
      class: App\Entity\Post
      index_if: config.indexable

In this case, the bundle will read this value.

1
2
3
4
class Post
{
    public $config = ['indexable' => false];
}

Connection errors

Are you getting “Impossible to connect”, “Unable to connect”, or “Unreachable hosts” errors? First, make sure the issue isn’t at your end:

  • Ensure you’re using the correct application ID and API key. Find these credentials on your Algolia dashboard.
  • Check for recent changes in your code.
  • Check the status of your data center provider.

If you’re using Firebase, you can only access Algolia from a paid Firebase tier.

If you can’t solve the problem yourself, contact the Algolia support team and provide them with the following information:

  • The name of your framework integration (Symfony) and its version number
  • A code snippet to reproduce the issue
  • Error message or stack trace (if applicable)
  • The name of the Algolia index that’s causing problems
  • The exact UTC time of the event
  • If you can’t connect to the Algolia API from your servers, send the output from the following command (run on any affected server):

    1
    
    curl -sL https://algolia.com/downloads/diag.sh > ./diag.sh && sudo ./diag.sh YourApplicationID
    

    Replace YourApplicationID with your Algolia application ID.

Indexing errors

Any “Record at the position XX objectID=XX is too big” errors during indexing are because you’ve exceeded the size limit for records. Reduce the size of your records and try again.

Did you find this page helpful?