Skip to main content
Meilisearch allows you to make multiple search requests at the same time with the /multi-search endpoint. A federated search is a multi-search that returns results from multiple queries in a single list. In this tutorial you will see how to create separate indexes containing different types of data from a CRM application. You will then perform a query searching all these indexes at the same time to obtain a single list of results.

Create three indexes

Download the following datasets: crm-chats.json, crm-profiles.json, and crm-tickets.json containing data from a fictional CRM application. Add the datasets to Meilisearch and create three separate indexes, profiles, chats, and tickets:
curl -X POST 'MEILISEARCH_URL/indexes/profiles' -H 'Content-Type: application/json' -H 'Authorization: Bearer MEILISEARCH_KEY' --data-binary @crm-profiles.json &&
curl -X POST 'MEILISEARCH_URL/indexes/chats' -H 'Content-Type: application/json' -H 'Authorization: Bearer MEILISEARCH_KEY' --data-binary @crm-chats.json &&
curl -X POST 'MEILISEARCH_URL/indexes/tickets' -H 'Content-Type: application/json' -H 'Authorization: Bearer MEILISEARCH_KEY' --data-binary @crm-tickets.json
Use the tasks endpoint to check the indexing status. Once Meilisearch successfully indexed all three datasets, you are ready to perform a federated search. When you are looking for Natasha Nguyen’s email address in your CRM application, you may not know whether you will find it in a chat log, among the existing customer profiles, or in a recent support ticket. In this situation, you can use federated search to search across all possible sources and receive a single list of results. Use the /multi-search endpoint with the federation parameter to query the three indexes simultaneously:
curl \
  -X POST 'MEILISEARCH_URL/multi-search' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "federation": {},
    "queries": [
      {
        "indexUid": "chats",
        "q": "natasha"
      },
      {
        "indexUid": "profiles",
        "q": "natasha"
      },
      {
        "indexUid": "tickets",
        "q": "natasha"
      }
    ]
  }'
Meilisearch should respond with a single list of search results:
{
  "hits": [
    {
      "id": 0,
      "client_name": "Natasha Nguyen",
      "message": "My email is natasha.nguyen@example.com",
      "time": 1727349362,
      "_federation": {
        "indexUid": "chats",
        "queriesPosition": 0
      }
    },

  ],
  "processingTimeMs": 0,
  "limit": 20,
  "offset": 0,
  "estimatedTotalHits": 3,
  "semanticHitCount": 0
}

Promote results from a specific index

Since this is a CRM application, users have profiles with their preferred contact information. If you want to search for Riccardo Rotondo’s preferred email, you can boost documents in the profiles index. Use the weight property of the federation parameter to boost results coming from a specific query:
curl \
  -X POST 'MEILISEARCH_URL/multi-search' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "federation": {},
    "queries": [
      {
        "indexUid": "chats",
        "q": "rotondo"
      },
      {
        "indexUid": "profiles",
        "q": "rotondo",
        "federationOptions": { "weight": 1.2 }
      },
      {
        "indexUid": "tickets",
        "q": "rotondo"
      }
    ]
  }'
This request will lead to results from the query targeting profile ranking higher than documents from other queries:
{
  "hits": [
  {
    "id": 1,
    "name": "Riccardo Rotondo",
    "email": "riccardo.rotondo@example.com",
      "_federation": {
        "indexUid": "profiles",
        "queriesPosition": 1
      }
    },

  ],
  "processingTimeMs": 0,
  "limit": 20,
  "offset": 0,
  "estimatedTotalHits": 3,
  "semanticHitCount": 0
}

Paginate federated results

By default, federated search returns a limited number of results using offset and limit. If you need exhaustive pagination, use the federation.page and federation.hitsPerPage parameters instead. These work like traditional page-based pagination across the merged result set. Send a federated search request with pagination:
curl \
  -X POST 'MEILISEARCH_URL/multi-search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer MEILISEARCH_KEY' \
  --data-binary '{
    "federation": {
      "page": 2,
      "hitsPerPage": 10
    },
    "queries": [
      { "indexUid": "profiles", "q": "Nguyen" },
      { "indexUid": "chats", "q": "Nguyen" },
      { "indexUid": "tickets", "q": "Nguyen" }
    ]
  }'
The response includes page, hitsPerPage, and totalPages instead of offset, limit, and estimatedTotalHits:
{
  "hits": [  ],
  "processingTimeMs": 1,
  "page": 2,
  "hitsPerPage": 10,
  "totalHits": 25,
  "totalPages": 3
}
This makes it straightforward to build paginated UIs that display merged results from multiple indexes.

Conclusion

You have created three indexes, then performed a federated multi-index search to receive all results in a single list. You then used weight to boost results from the index most likely to contain the information you wanted, and paginated through merged results using federation.page and federation.hitsPerPage.

Next steps

Boost results across indexes

Fine-tune result ranking when combining results from multiple indexes.

Build a unified search bar

Create a single search interface that queries multiple indexes at once.

Multi-search overview

Learn about multi-search capabilities and when to use them.