Quick start
This quick tour will help you get started with MeiliSearch in just a few steps.
All that is required is a command line
(opens new window) for installation, and some way to interact with MeiliSearch afterwards (e.g. cURL
(opens new window) or one of our SDKs). You can find instructions to install each of our SDKs further down in the add documents section of this guide.
Download and launch
First of all, let’s download and run MeiliSearch.
curl -L https://install.meilisearch.com | sh./meilisearch
You should see the following response:
888b d888 d8b 888 d8b .d8888b. 8888888b d8888 Y8P 888 Y8P d88P Y88b 88888888b.d88888 888 Y88b. 888888Y88888P888 .d88b. 888 888 888 "Y888b. .d88b. 8888b. 888d888 .d8888b 88888b.888 Y888P 888 d8P Y8b 888 888 888 "Y88b. d8P Y8b "88b 888P" d88P" 888 "88b888 Y8P 888 88888888 888 888 888 "888 88888888 .d888888 888 888 888 888888 " 888 Y8b. 888 888 888 Y88b d88P Y8b. 888 888 888 Y88b. 888 888888 888 "Y8888 888 888 888 "Y8888P" "Y8888 "Y888888 888 "Y8888P 888 888Database path: "./data.ms"Server listening on: "127.0.0.1:7700"
You can download & run MeiliSearch in many different ways (i.e: docker, apt, homebrew, …).
Environment variables and options can be set before and on launch to configure MeiliSearch. Amongst all the options, you can use the master key and the port options.
Communicate with MeiliSearch
Now that your MeiliSearch server is up and running, you should be able to communicate with it.
Communication to the server is done through a RESTful API or one of our SDKs.
Add documents
To add documents to MeiliSearch you must provide:
- Documents in the form of an array of JSON objects.
- An index name (uid). An index is where the documents are stored.
If the index does not exist, MeiliSearch creates it when you first add documents.
To be processed, all documents must share one common field
A field, or a key-value pair, is a set of two data items linked together: an attribute and its associated value.
Ex: "attribute": "value"
which will serve as [primary key
An attribute that must be present in every document of a given index, used to identify and distinguish documents.
Example: In a document with the primary field "id": "Abc_012", “id” is the index’s primary key and “Abc_012” is the document’s unique identifier.
]($646dd5f874873bbe.md#primary-key)for the document. Values in that field must always be unique.
[ { "id": "123", "title": "Superman" }]
The primary key is id, the document’s unique identifier is 123.
There are several ways to let MeiliSearch know what the primary key is. The easiest one is to have an attribute
An attribute is the name of a field, like a key.
Ex: "title": "Batman"In the example above, “title” is the attribute.
that contains the string id in a case-insensitive manner.
Below is an example to showcase how to add documents to an index called movies. To follow along, first click this link to download the file: movies.json. Then, move the downloaded file to your working directory.
cURL
curl \ -X POST 'http://127.0.0.1:7700/indexes/movies/documents' \ --data @movies.json
JavaScript
npm install meilisearch
Or, if you are using yarn
yarn add meilisearch
Import
require syntax:
const { MeiliSearch } = require('meilisearch')const movies = require('./movies.json')
import syntax:
import { MeiliSearch } from 'meilisearch'import movies from '../small_movies.json'
Use
const client = new MeiliSearch({ host: 'http://127.0.0.1:7700' })client.index('movie').addDocuments(movies) .then((res) => console.log(res))
About this SDK
Python
pip3 install meilisearch
import meilisearchimport jsonclient = meilisearch.Client('http://127.0.0.1:7700')json_file = open('movies.json')movies = json.load(json_file)client.index('movies').add_documents(movies)
About this SDK
PHP
Using meilisearch-php with the Guzzle HTTP client:
composer require meilisearch/meilisearch-php \ guzzlehttp/guzzle \ http-interop/http-factory-guzzle:^1.0
index('movies')->addDocuments($movies);
About this SDK
Ruby
$ bundle add meilisearch
require 'json'require 'meilisearch'client = MeiliSearch::Client.new('http://127.0.0.1:7700')movies_json = File.read('movies.json')movies = JSON.parse(movies_json)client.index('movies').add_documents(movies)
About this SDK
Go
go get -u github.com/meilisearch/meilisearch-go
package mainimport ( "os" "encoding/json" "io/ioutil" "github.com/meilisearch/meilisearch-go")func main() { client := meilisearch.NewClient(meilisearch.ClientConfig{ Host: "http://127.0.0.1:7700", }) jsonFile, _ := os.Open("movies.json") defer jsonFile.Close() byteValue, _ := ioutil.ReadAll(jsonFile) var movies []map[string]interface{} json.Unmarshal(byteValue, &movies) _, err := client.Index("movies").AddDocuments(movies) if err != nil { panic(err) }}
About this SDK
Rust
[dependencies] meilisearch-sdk = "0.10" # futures: because we want to block on futures futures = "0.3" # serde: required if you are going to use documents serde = { version="1.0", features = ["derive"] } # serde_json: required in some parts of this guide serde_json = "1.0"
Documents in the Rust library are strongly typed. You have to implement the Document trait on a struct to be able to use it with Meilisearch.
#[derive(Serialize, Deserialize, Debug)]struct Movie { id: String, title: String, poster: String, overview: String, release_date: i64, genres: Vec}impl Document for Movie { type UIDType = String; fn get_uid(&self) -> &Self::UIDType { &self.id }}
You will often need this Movie struct in other parts of this documentation. (you will have to change it a bit sometimes) You can also use schemaless values, by putting a serde_json::Value inside your own struct like this:
#[derive(Serialize, Deserialize, Debug)]struct Movie { id: String, #[serde(flatten)] value: serde_json::Value,}impl Document for Movie { type UIDType = String; fn get_uid(&self) -> &Self::UIDType { &self.id }}
Then, add documents into the index:
use meilisearch_sdk::{ indexes::*, document::*, client::*, search::*, progress::*, settings::*};use serde::{Serialize, Deserialize};use std::{io::prelude::*, fs::File};use futures::executor::block_on;fn main() { block_on(async move { let client = Client::new("http://localhost:7700", "masterKey"); // reading and parsing the file let mut file = File::open("movies.json").unwrap(); let mut content = String::new(); file.read_to_string(&mut content).unwrap(); let movies_docs: Vec = serde_json::from_str(&content).unwrap(); // adding documents let movies = client.get_or_create_index("movies").await.unwrap(); movies.add_documents(&movies_docs, None).await.unwrap();})}
About this SDK
API references
Checking updates
Most actions in MeiliSearch are asynchronous, including the document addition process.
Asynchronous actions return a JSON object that contains only an updateId attribute. This is a successful response, indicating that the operation has been taken into account, but may not have been executed yet.
You can check the status of the operation via the updateId and the get update status route. Checking the update status of an operation is never mandatory, but can prove useful in tracing the origin of errors or unexpected behavior.
See our guide on asynchronous updates or the updates API reference for more information.
Search
Now that your documents have been ingested into MeiliSearch, you are able to search them.
MeiliSearch offers many parameters that you can play with to refine your search or change the format of the returned documents. However, by default, the search is already relevant.
The search engine is now aware of your documents and can serve those via an HTTP server.
cURL
curl 'http://127.0.0.1:7700/indexes/movies/search' \--data '{ "q": "botman" }'
JavaScript
client.index('movies').search('botman').then((res) => console.log(res))
About this SDK
Python
client.index('movies').search('botman')
About this SDK
PHP
$client->index('movies')->search('botman');
About this SDK
Ruby
client.index('movies').search('botman')
About this SDK
Go
resp, err := client.Index("movies").Search("botman", &meilisearch.SearchRequest{})if err != nil { panic(err)}
About this SDK
Rust
You can build a Query and execute it later:
let query: Query = Query::new(&movies) .with_query("botman") .build();let results: SearchResults = movies.execute_query(&query).await.unwrap();
You can build a Query and execute it directly:
let results: SearchResults = Query::new(&movies) .with_query("botman") .execute() .await .unwrap();
You can search in an index directly:
let results: SearchResults = movies.search() .with_query("botman") .execute() .await .unwrap();
About this SDK
MeiliSearch response:
{ "hits": [ { "id": "29751", "title": "Batman Unmasked: The Psychology of the Dark Knight", "poster": "https://image.tmdb.org/t/p/w1280/jjHu128XLARc2k4cJrblAvZe0HE.jpg", "overview": "Delve into the world of Batman and the vigilante justice tha", "release_date": "2008-07-15" }, { "id": "471474", "title": "Batman: Gotham by Gaslight", "poster": "https://image.tmdb.org/t/p/w1280/7souLi5zqQCnpZVghaXv0Wowi0y.jpg", "overview": "ve Victorian Age Gotham City, Batman begins his war on crime", "release_date": "2018-01-12" } ... ], "offset": 0, "limit": 20, "processingTimeMs": 2, "query": "botman"}
API references
Web interface
We also deliver an out-of-the-box web interface in which you can test MeiliSearch interactively.
To do so, open your web browser and enter MeiliSearch address (in our case: http://127.0.0.1:7700) into the browser address bar.This will lead you to a web page with a search bar that will allow you to search in the selected index.
Integrate with your project
The only step missing now is adding the search bar to your project. The easiest way of achieving this is to use instant-meilisearch
(opens new window): a developer tool that generates all the search components needed to start searching.
Instant MeiliSearch
(opens new window) works on common front-end environments, such as JavaScript
(opens new window), React
(opens new window), and Vue.js
(opens new window).
instant-meilisearch uses InstantSearch
(opens new window) an open-source library that generates everything you need from a search interface.
Let’s try!
- Create an html file, for example, index.html.
- Open it in a text editor (e.g. Notepad, Sublime Text, Visual Studio Code).
- Copy-paste any of the code examples below and save the file.
- Open index.html in your browser (double click on it in your folder).
We use browser builds for ease of integration. It is possible to do this with npm or yarn. Please refer to instant-meilisearch
(opens new window) for documentation.
JavaScript
Vue.js
React
The following code sample uses plain JavaScript
(opens new window).
const search = instantsearch({ indexName: "movies", searchClient: instantMeiliSearch( "http://localhost:7700" ) }); search.addWidgets([ instantsearch.widgets.searchBox({ container: "#searchbox" }), instantsearch.widgets.configure({ hitsPerPage: 8 }), instantsearch.widgets.hits({ container: "#hits", templates: { item: ` {{#helpers.highlight}}{ "attribute": "title" }{{/helpers.highlight}} ` } }) ]); search.start();
The code above comes in multiple parts:
- The first four lines of the add both searchbox and hits elements. Ultimately, instant-meilisearch adds the search bar and search results in these elements.
