Articles on: Getting started

How to setup Meilisearch with JavaScript

Installation



We recommend installing meilisearch-js in your project with your package manager of choice.

npm install meilisearch


meilisearch-js officially supports node versions >= 14 and <= 18.

Instead of using a package manager, you may also import the library directly into your HTML via a CDN.

Run Meilisearch



To use one of our SDKs, you must first have a running Meilisearch instance. Consult our documentation for instructions on how to download and launch Meilisearch.

Import



After installing meilisearch-js, you must import it into your application. There are many ways of doing that depending on your development environment.

import syntax



Usage in an ES module environment:

import { MeiliSearch } from 'meilisearch'

const client = new MeiliSearch({
  host: 'url',
  apiKey: 'masterKey',
})


<script> tag



Usage in an HTML (or alike) file:

<script src='https://cdn.jsdelivr.net/npm/meilisearch@latest/dist/bundles/meilisearch.umd.js'></script>
<script>
  const client = new MeiliSearch({
    host: 'url',
    apiKey: 'masterKey',
  })
</script>


require syntax



Usage in a back-end node.js or another environment supporting CommonJS modules:

const { MeiliSearch } = require('meilisearch')

const client = new MeiliSearch({
  host: 'url',
  apiKey: 'masterKey',
})


React Native



To use meilisearch-js with React Native, you must also install react-native-url-polyfill.

Deno



Usage in a Deno environment:

import { MeiliSearch } from "https://esm.sh/meilisearch"

const client = new MeiliSearch({
  host: 'url',
  apiKey: 'masterKey',
})


Getting started



Add documents



const { MeiliSearch } = require('meilisearch')
// Or if you are in a ES environment
import { MeiliSearch } from 'meilisearch'

;(async () => {
  const client = new MeiliSearch({
    host: 'url',
    apiKey: 'masterKey',
  })

  // An index is where the documents are stored.
  const index = client.index('movies')

  const documents = [
      { id: 1, title: 'Carol', genres: ['Romance', 'Drama'] },
      { id: 2, title: 'Wonder Woman', genres: ['Action', 'Adventure'] },
      { id: 3, title: 'Life of Pi', genres: ['Adventure', 'Drama'] },
      { id: 4, title: 'Mad Max: Fury Road', genres: ['Adventure', 'Science Fiction'] },
      { id: 5, title: 'Moana', genres: ['Fantasy', 'Action']},
      { id: 6, title: 'Philadelphia', genres: ['Drama'] },
  ]

  // If the index 'movies' does not exist, Meilisearch creates it when you first add the documents.
  let response = await index.addDocuments(documents)

  console.log(response) // => { "uid": 0 }
})()


Tasks such as document addition always return a unique identifier. You can use this identifier taskUid to check the status (enqueued, processing, succeeded or failed) of a task.



// Meilisearch is typo-tolerant:
const search = await index.search('philoudelphia')
console.log(search)


Output:

{
  "hits": [
    {
      "id": "6",
      "title": "Philadelphia",
      "genres": ["Drama"]
    }
  ],
  "offset": 0,
  "limit": 20,
  "estimatedTotalHits": 1,
  "processingTimeMs": 1,
  "query": "philoudelphia"
}


Using search parameters



meilisearch-js supports all search parameters described in our main documentation website.

await index.search(
  'wonder',
  {
    attributesToHighlight: ['*']
  }
)


{
  "hits": [
    {
      "id": 2,
      "title": "Wonder Woman",
      "genres": ["Action", "Adventure"],
      "_formatted": {
        "id": "2",
        "title": "<em>Wonder</em> Woman",
        "genres": ["Action", "Adventure"]
      }
    }
  ],
  "offset": 0,
  "limit": 20,
  "estimatedTotalHits": 1,
  "processingTimeMs": 0,
  "query": "wonder"
}


Custom search with filters



To enable filtering, you must first add your attributes to the `filterableAttributes` index setting.

await index.updateAttributesForFaceting([
    'id',
    'genres'
  ])


You only need to perform this operation once per index.

Note that Meilisearch rebuilds your index whenever you update filterableAttributes. Depending on the size of your dataset, this might take considerable time. You can track the process using the tasks API).

After you configured filterableAttributes, you can use the `filter` search parameter to refine your search:

await index.search(
  'wonder',
  {
    filter: ['id > 1 AND genres = Action']
  }
)


{
  "hits": [
    {
      "id": 2,
      "title": "Wonder Woman",
      "genres": ["Action","Adventure"]
    }
  ],
  "offset": 0,
  "limit": 20,
  "estimatedTotalHits": 1,
  "processingTimeMs": 0,
  "query": "wonder"
}




Placeholder search makes it possible to receive hits based on your parameters without having any query (q). For example, in a movies database you can run an empty query to receive all results filtered by genre.

await index.search(
  '',
  {
    filter: ['genres = fantasy'],
    facets: ['genres']
  }
)


{
  "hits": [
    {
      "id": 2,
      "title": "Wonder Woman",
      "genres": ["Action","Adventure"]
    },
    {
      "id": 5,
      "title": "Moana",
      "genres": ["Fantasy","Action"]
    }
  ],
  "offset": 0,
  "limit": 20,
  "estimatedTotalHits": 2,
  "processingTimeMs": 0,
  "query": "",
  "facetDistribution": {
    "genres": {
      "Action": 2,
      "Fantasy": 1,
      "Adventure": 1
    }
  }
}


Note that to enable faceted search on your dataset you need to add genres to the filterableAttributes index setting. For more information on filtering and faceting, consult our documentation settings.



You can abort a pending search request by providing an AbortSignal to the request.

const controller = new AbortController()

index
  .search('wonder', {}, {
    signal: controller.signal,
  })
  .then((response) => {
    /** ... */
  })
  .catch((e) => {
    /** Catch AbortError here. */
  })

controller.abort()


API resources





Make a search request



client.index<T>('xxx').search(query: string, options: SearchParams = {}, config?: Partial<Request>): Promise<SearchResponse<T>>


Make a search request using the GET method (slower than the search method)



client.index<T>('xxx').searchGet(query: string, options: SearchParams = {}, config?: Partial<Request>): Promise<SearchResponse<T>>






client.multiSearch(queries?: MultiSearchParams, config?: Partial<Request>): Promise<Promise<MultiSearchResponse<T>>>


multiSearch uses the POST method when performing its request to Meilisearch.

Search For Facet Values





client.index<T>('myIndex').searchForFacetValues(params: SearchForFacetValuesParams, config?: Partial<Request>): Promise<SearchForFacetValuesResponse>


Documents



Add or replace multiple documents



client.index('myIndex').addDocuments(documents: Document<T>[]): Promise<EnqueuedTask>


Add or replace multiple documents in string format



client.index('myIndex').addDocumentsFromString(documents: string, contentType: ContentType, queryParams: RawDocumentAdditionOptions): Promise<EnqueuedTask>


Add or replace multiple documents in batches



client.index('myIndex').addDocumentsInBatches(documents: Document<T>[], batchSize = 1000): Promise<EnqueuedTask[]>


Add or update multiple documents



client.index('myIndex').updateDocuments(documents: Array<Document<Partial<T>>>): Promise<EnqueuedTask>


Add or update multiple documents in string format



client.index('myIndex').updateDocumentsFromString(documents: string, contentType: ContentType, queryParams: RawDocumentAdditionOptions): Promise<EnqueuedTask>


Add or update multiple documents in batches



client.index('myIndex').updateDocumentsInBatches(documents: Array<Document<Partial<T>>>, batchSize = 1000): Promise<EnqueuedTask[]>


Get Documents



client.index.getDocuments(parameters: DocumentsQuery = {}): Promise<DocumentsResults<T>>>


Get one document



client.index('myIndex').getDocument(documentId: string): Promise<Document<T>>


Delete one document



client.index('myIndex').deleteDocument(documentId: string | number): Promise<EnqueuedTask>


Delete multiple documents



client.index('myIndex').deleteDocuments(params: DocumentsDeletionQuery | DocumentsIds): Promise<EnqueuedTask>


Delete all documents



client.index('myIndex').deleteAllDocuments(): Promise<Types.EnqueuedTask>


Tasks



Get all tasks



client.getTasks(parameters: TasksQuery): Promise<TasksResults>


Get one task



client.getTask(uid: number): Promise<Task>


Delete tasks



client.deleteTasks(parameters: DeleteTasksQuery = {}): Promise<EnqueuedTask>


Cancel tasks



client.cancelTasks(parameters: CancelTasksQuery = {}): Promise<EnqueuedTask>


Get all tasks of an index



client.index('myIndex').getTasks(parameters: TasksQuery): Promise<TasksResults>


Get one task of an index



client.index('myIndex').getTask(uid: number): Promise<Task>



Wait for one task




Using the client


client.waitForTask(uid: number, { timeOutMs?: number, intervalMs?: number }): Promise<Task>


Using the index


client.index('myIndex').waitForTask(uid: number, { timeOutMs?: number, intervalMs?: number }): Promise<Task>


Wait for multiple tasks



Using the client


client.waitForTasks(uids: number[], { timeOutMs?: number, intervalMs?: number }): Promise<Task[]>


Using the index


client.index('myIndex').waitForTasks(uids: number[], { timeOutMs?: number, intervalMs?: number }): Promise<Task[]>


Indexes



Get all indexes in Index instances



client.getIndexes(parameters: IndexesQuery): Promise<IndexesResults<Index[]>>


Get all indexes



client.getRawIndexes(parameters: IndexesQuery): Promise<IndexesResults<IndexObject[]>>



Create a new index



client.createIndex<T>(uid: string, options?: IndexOptions): Promise<EnqueuedTask>


Create a local reference to an index



client.index<T>(uid: string): Index<T>


Get an index instance completed with information fetched from Meilisearch



client.getIndex<T>(uid: string): Promise<Index<T>>


Get the raw index JSON response from Meilisearch



client.getRawIndex(uid: string): Promise<IndexObject>


Get an object with information about the index



client.index('myIndex').getRawInfo(): Promise<IndexObject>


Update Index



Using the client


client.updateIndex(uid: string, options: IndexOptions): Promise<EnqueuedTask>


Using the index object


client.index('myIndex').update(data: IndexOptions): Promise<EnqueuedTask>


Delete index



Using the client

client.deleteIndex(uid): Promise<void>


Using the index object

client.index('myIndex').delete(): Promise<void>


Get specific index stats



client.index('myIndex').getStats(): Promise<IndexStats>


Return Index instance with updated information


client.index('myIndex').fetchInfo(): Promise<Index>


Get Primary Key of an Index


client.index('myIndex').fetchPrimaryKey(): Promise<string | undefined>


Swap two indexes


client.swapIndexes(params: SwapIndexesParams): Promise<EnqueuedTask>


Settings



Get settings



client.index('myIndex').getSettings(): Promise<Settings>


Update settings



client.index('myIndex').updateSettings(settings: Settings): Promise<EnqueuedTask>


Reset settings



client.index('myIndex').resetSettings(): Promise<EnqueuedTask>


Pagination Settings



Get pagination



client.index('myIndex').getPagination(): Promise<PaginationSettings>


Update pagination



client.index('myIndex').updatePagination(pagination: PaginationSettings): Promise<EnqueuedTask>


Reset pagination



client.index('myIndex').resetPagination(): Promise<EnqueuedTask>


Synonyms



Get synonyms



client.index('myIndex').getSynonyms(): Promise<Synonyms>


Update synonyms



client.index('myIndex').updateSynonyms(synonyms: Synonyms): Promise<EnqueuedTask>


Reset synonyms



client.index('myIndex').resetSynonyms(): Promise<EnqueuedTask>


Stop words



Get stop words



client.index('myIndex').getStopWords(): Promise<string[]>


Update stop words



client.index('myIndex').updateStopWords(stopWords: string[] | null ): Promise<EnqueuedTask>


Reset stop words



client.index('myIndex').resetStopWords(): Promise<EnqueuedTask>


Ranking rules



Get ranking rules



client.index('myIndex').getRankingRules(): Promise<string[]>


Update ranking rules



client.index('myIndex').updateRankingRules(rankingRules: string[] | null): Promise<EnqueuedTask>


Reset ranking rules



client.index('myIndex').resetRankingRules(): Promise<EnqueuedTask>


Distinct Attribute



Get distinct attribute



client.index('myIndex').getDistinctAttribute(): Promise<string | void>


Update distinct attribute



client.index('myIndex').updateDistinctAttribute(distinctAttribute: string | null): Promise<EnqueuedTask>


Reset distinct attribute



client.index('myIndex').resetDistinctAttribute(): Promise<EnqueuedTask>


Searchable attributes



Get searchable attributes



client.index('myIndex').getSearchableAttributes(): Promise<string[]>


Update searchable attributes



client.index('myIndex').updateSearchableAttributes(searchableAttributes: string[] | null): Promise<EnqueuedTask>


Reset searchable attributes



client.index('myIndex').resetSearchableAttributes(): Promise<EnqueuedTask>


Displayed attributes



Get displayed attributes



client.index('myIndex').getDisplayedAttributes(): Promise<string[]>


Update displayed attributes



client.index('myIndex').updateDisplayedAttributes(displayedAttributes: string[] | null): Promise<EnqueuedTask>


Reset displayed attributes



client.index('myIndex').resetDisplayedAttributes(): Promise<EnqueuedTask>


Filterable attributes



Get filterable attributes



client.index('myIndex').getFilterableAttributes(): Promise<string[]>


Update filterable attributes



client.index('myIndex').updateFilterableAttributes(filterableAttributes: string[] | null): Promise<EnqueuedTask>


Reset filterable attributes



client.index('myIndex').resetFilterableAttributes(): Promise<EnqueuedTask>


Sortable attributes



Get sortable attributes



client.index('myIndex').getSortableAttributes(): Promise<string[]>


Update sortable attributes



client.index('myIndex').updateSortableAttributes(sortableAttributes: string[] | null): Promise<EnqueuedTask>


Reset sortable attributes



client.index('myIndex').resetSortableAttributes(): Promise<EnqueuedTask>


Faceting



Get faceting



client.index('myIndex').getFaceting(): Promise<Faceting>


Update faceting



client.index('myIndex').updateFaceting(faceting: Faceting): Promise<EnqueuedTask>


Reset faceting



client.index('myIndex').resetFaceting(): Promise<EnqueuedTask>


Typo tolerance



Get typo tolerance



client.index('myIndex').getTypoTolerance(): Promise<TypoTolerance>


Update typo tolerance



client.index('myIndex').updateTypoTolerance(typoTolerance: TypoTolerance | null): Promise<EnqueuedTask>


Reset typo tolerance



client.index('myIndex').resetTypoTolerance(): Promise<EnqueuedTask>


Keys



Get keys



client.getKeys(parameters: KeysQuery): Promise<KeysResults>


Get one key



client.getKey(keyOrUid: string): Promise<Key>


Create a key



client.createKey(options: KeyCreation): Promise<Key>


Update a key



client.updateKey(keyOrUid: string, options: KeyUpdate): Promise<Key>


Delete a key



client.deleteKey(keyOrUid: string): Promise<void>


isHealthy



Return true or false depending on the health of the server



client.isHealthy(): Promise<boolean>


Health



Check if the server is healthy



client.health(): Promise<Health>


Stats



Get database stats



client.getStats(): Promise<Stats>


Version



Get binary version



client.getVersion(): Promise<Version>


Dump



Trigger a dump creation process



client.createDump(): Promise<EnqueuedTask>

Updated on: 23/08/2023

Was this article helpful?

Share your feedback

Cancel

Thank you!