To search in multiple entities at the same time, use aggregators.
Aggregators let you index multiple entities in a single index.
Define aggregators
To create a new aggregator, add a new class to your entities directory.
The getEntities
method of this class should return all the entity classes you want to index:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Algolia\SearchBundle\Entity\Aggregator;
/**
* @ORM\Entity
*/
class News extends Aggregator
{
/**
* Returns the entities class names that should be aggregated.
*
* @return string[]
*/
public static function getEntities()
{
return [
Post::class,
Comment::class,
];
}
}
If you’re using a NoSQL database like MongoDB,
use the Algolia\SearchBundle\Document\Aggregator
class instead.
Finally, add the new aggregator class name to the algolia_search.yml
file:
- indices:
- name: news
class: App\Entity\News
Search
An aggregator is a standard entity class.
To start searching entities on the aggregator, use the search
method of your
SearchService:
$this->searchService->index($objectManager, $post);
$this->searchService->index($objectManager, $comment);
$results = $this->searchService->search($objectManager, News::class, 'query');
// $results[0] contains a \App\Entity\Post.
// $results[1] contains a \App\Entity\Comment.
Be careful, the $result
array may contain different types of entities instances.
To get the raw results from Algolia,
use the rawSearch
method.
However, each result might have a different structure:
$results = $this->searchService->rawSearch(News::class, 'query');
{
"hits": [
{
"id": 1,
"title": "Article title",
"slug": "article-title",
"content": "Article content by query",
"objectID": "App\\Entity\\Article::1"
},
{
"id": 1,
"content": "Comment content by query",
"objectID": "App\\Entity\\Comment::1"
}
]
}
To ensure that each result has a similar structure,
implement the normalize
method
on each entity or override it on the aggregator class.
Conditional indexing
Conditional indexing on aggregators works just like a normal entity, using the index_if
key.
Use $this->entity
to have access to the current entity being aggregated.
Here is an example using the method approach:
- indices:
- name: news
class: App\Entity\News
index_if: isPublished
/**
* @ORM\Entity
*/
class News extends Aggregator
{
// ...
public function isPublished()
{
// Index only published articles.
if ($this->entity instanceof Article) {
return $this->entity->isPublished();
}
// If is not an article, index anyway.
return true;
}
}
For more information, see Conditional indexing.