Work with Elasticsearch

Learn how to index, update, retrieve, search and delete documents in an Elasticsearch cluster.

Before you begin

To use these steps, you need to have the curl command available from the command line.

To find out what the FOUNDELASTICSEARCH_URL is for your Elasticsearch cluster, grep on the output of the heroku config command for your app:

heroku config --app MY_APP | grep FOUNDELASTICSEARCH_URL


To index documents, POST documents to Elasticsearch:

curl https://FOUNDELASTICSEARCH_URL/my_index/my_type -XPOST -d '{
    "title": "One", "tags": ["ruby"]

In this example, the index my_index is created dynamically when the first document is inserted into it. All documents in Elasticsearch have a type and an id, which is echoed as _type and _id in the JSON responses. If no id is specified during indexing, a random id is generated.

Bulk indexing

To achieve the best possible performance, we recommed that you use the bulk API.

To index some additional documents using the bulk API:

curl https://FOUNDELASTICSEARCH_URL/my_index/my_type/_bulk -XPOST -d '
{"index": {}}
{"title": "Two", "tags": ["ruby", "python"] }
{"index": {}}
{"title": "Three", "tags": ["java"] }
{"index": {}}
{"title": "Four", "tags": ["ruby", "php"] }

Elasticsearch should return output similar to this:

{"took":10, "items": [


To update an existing document in Elasticsearch, simply POST the updated document to http://FOUNDELASTICSEARCH_URL/my_index/my_type/<id>, where <id> is the id of the document.

For example, to update the last document indexed from the previous example:

curl https://FOUNDELASTICSEARCH_URL/my_index/my_type/_b-kbI1MREmi9SeixFNEVw -XPOST -d '{
    "title": "Four updated", "tags": ["ruby", "php"]

As you can see, the document is updated and the _version counter is automatically incremented.

Retrieving documents

You can take a look at the data you indexed by issuing a GET request for a specific document:

curl https://FOUNDELASTICSEARCH_URL/my_index/my_type/_b-kbI1MREmi9SeixFNEVw
{"exists":true,"_index":"my_index","_type":"my_type","_id":"_b-kbI1MREmi9SeixFNEVw","_version":2,"_source":{"title": "Four updated", "tags": ["ruby", "php"]}}

If Elasticsearch finds the document, it returns a HTTP status code of 200 OK and sets exists: true in the result. Otherwise, a HTTP status code of 404 Not Found gets returned and the result contains exists: false.


You can issue search requests to the following Elasticsearch endpoints:


Either a HTTP GET or a HTTP POST request works. To search using a HTTP GET request, use URI parameters to specify your query:

curl https://FOUNDELASTICSEARCH_URL/my_index/my_type/_search?q=title:T*

A full explanation of the allowed parameters can be found in the Elasticsearch URI Request documentation.

In order to perform more complicated queries, use HTTP POST requests to search. In the following example, we search by creating a facet on the tags field:

curl https://FOUNDELASTICSEARCH_URL/my_index/my_type/_search?pretty=true -XPOST -d '{
    "query": {
        "query_string": {"query": "*"}
    "facets": {
        "tags": {
            "terms": {"field": "tags"}

We added ?pretty=true to the request, which makes Elasticsearch return a more human readable JSON response. For performance reasons, ?pretty=true is not recommended in production.

You can find a full explanation of how the request body is structured in the Elasticsearch Request Body documentation.

To execute multiple queries in one request, use the Multi Search API.


You delete documents from Elasticsearch by sending HTTP DELETE requests.

To delete a single document:

curl https://FOUNDELASTICSEARCH_URL/{index}/{type}/{id} -XDELETE

To delete all documents of a given type:

curl https://FOUNDELASTICSEARCH_URL/{index}/{type} -XDELETE

To delete a whole index: