========
Java API
========

Preface
=======

This section describes the Java API that elasticsearch provides. All
elasticsearch operations are executed using a `Client <#client>`__
object. All operations are completely asynchronous in nature (either
accepts a listener, or returns a future).

Additionally, operations on a client may be accumulated and executed in
`Bulk <#bulk>`__.

Note, all the APIs are exposed through the Java API (actually, the Java
API is used internally to execute them).

Maven Repository
================

Elasticsearch is hosted on `Maven
Central <http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22elasticsearch%22>`__.

For example, you can define the latest version in your ``pom.xml`` file:

.. code:: xml

    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>${es.version}</version>
    </dependency>

Client
======

You can use the **Java client** in multiple ways:

-  Perform standard `index <#index_>`__, `get <#get>`__,
   `delete <#delete>`__ and `search <#search>`__ operations on an
   existing cluster

-  Perform administrative tasks on a running cluster

-  Start full nodes when you want to run Elasticsearch embedded in your
   own application or when you want to launch unit or integration tests

Obtaining an elasticsearch ``Client`` is simple. The most common way to
get a client is by:

1. Creating an embedded ```Node`` <#node-client>`__ that acts as a node
   within a cluster.

2. Requesting a ``Client`` from your embedded ``Node``.

Another manner is by creating a
```TransportClient`` <#transport-client>`__ that connects to a cluster.

**Important:**

    Please note that you are encouraged to use the same version on
    client and cluster sides. You may hit some incompatibility issues
    when mixing major versions.

Node Client
-----------

Instantiating a node based client is the simplest way to get a
``Client`` that can execute operations against elasticsearch.

.. code:: java

    import static org.elasticsearch.node.NodeBuilder.*;

    // on startup

    Node node = nodeBuilder().node();
    Client client = node.client();

    // on shutdown

    node.close();

When you start a ``Node``, it joins an elasticsearch cluster. You can
have different clusters by simply setting the ``cluster.name`` setting,
or explicitly using the ``clusterName`` method on the builder.

You can define ``cluster.name`` in the
``/src/main/resources/elasticsearch.yml`` file in your project. As long
as ``elasticsearch.yml`` is present in the classpath, it will be used
when you start your node.

.. code:: yaml

    cluster.name: yourclustername

Or in Java:

.. code:: java

    Node node = nodeBuilder().clusterName("yourclustername").node();
    Client client = node.client();

The benefit of using the ``Client`` is the fact that operations are
automatically routed to the node(s) the operations need to be executed
on, without performing a "double hop". For example, the index operation
will automatically be executed on the shard that it will end up existing
at.

When you start a ``Node``, the most important decision is whether it
should hold data or not. In other words, should indices and shards be
allocated to it. Many times we would like to have the clients just be
clients, without shards being allocated to them. This is simple to
configure by setting either ``node.data`` setting to ``false`` or
``node.client`` to ``true`` (the ``NodeBuilder`` respective helper
methods on it):

.. code:: java

    import static org.elasticsearch.node.NodeBuilder.*;

    // on startup

    Node node = nodeBuilder().client(true).node();
    Client client = node.client();

    // on shutdown

    node.close();

Another common usage is to start the ``Node`` and use the ``Client`` in
unit/integration tests. In such a case, we would like to start a "local"
``Node`` (with a "local" discovery and transport). Again, this is just a
matter of a simple setting when starting the ``Node``. Note, "local"
here means local on the JVM (well, actually class loader) level, meaning
that two **local** servers started within the same JVM will discover
themselves and form a cluster.

.. code:: java

    import static org.elasticsearch.node.NodeBuilder.*;

    // on startup

    Node node = nodeBuilder().local(true).node();
    Client client = node.client();

    // on shutdown

    node.close();

Transport Client
----------------

The ``TransportClient`` connects remotely to an elasticsearch cluster
using the transport module. It does not join the cluster, but simply
gets one or more initial transport addresses and communicates with them
in round robin fashion on each action (though most actions will probably
be "two hop" operations).

.. code:: java

    // on startup

    Client client = new TransportClient()
            .addTransportAddress(new InetSocketTransportAddress("host1", 9300))
            .addTransportAddress(new InetSocketTransportAddress("host2", 9300));

    // on shutdown

    client.close();

Note that you have to set the cluster name if you use one different than
"elasticsearch":

.. code:: java

    Settings settings = ImmutableSettings.settingsBuilder()
            .put("cluster.name", "myClusterName").build();
    Client client =    new TransportClient(settings);
    //Add transport addresses and do something with the client...

Or using ``elasticsearch.yml`` file as shown in ?

The client allows to sniff the rest of the cluster, and add those into
its list of machines to use. In this case, note that the IP addresses
used will be the ones that the other nodes were started with (the
"publish" address). In order to enable it, set the
``client.transport.sniff`` to ``true``:

.. code:: java

    Settings settings = ImmutableSettings.settingsBuilder()
            .put("client.transport.sniff", true).build();
    TransportClient client = new TransportClient(settings);

Other transport client level settings include:

+--------------------------------------+--------------------------------------+
| Parameter                            | Description                          |
+======================================+======================================+
| ``client.transport.ignore_cluster_na | Set to ``true`` to ignore cluster    |
| me``                                 | name validation of connected nodes.  |
|                                      | (since 0.19.4)                       |
+--------------------------------------+--------------------------------------+
| ``client.transport.ping_timeout``    | The time to wait for a ping response |
|                                      | from a node. Defaults to ``5s``.     |
+--------------------------------------+--------------------------------------+
| ``client.transport.nodes_sampler_int | How often to sample / ping the nodes |
| erval``                              | listed and connected. Defaults to    |
|                                      | ``5s``.                              |
+--------------------------------------+--------------------------------------+

Index API
=========

The index API allows one to index a typed JSON document into a specific
index and make it searchable.

Generate JSON document
----------------------

There are several different ways of generating a JSON document:

-  Manually (aka do it yourself) using native ``byte[]`` or as a
   ``String``

-  Using a ``Map`` that will be automatically converted to its JSON
   equivalent

-  Using a third party library to serialize your beans such as
   `Jackson <http://wiki.fasterxml.com/JacksonHome>`__

-  Using built-in helpers XContentFactory.jsonBuilder()

Internally, each type is converted to ``byte[]`` (so a String is
converted to a ``byte[]``). Therefore, if the object is in this form
already, then use it. The ``jsonBuilder`` is highly optimized JSON
generator that directly constructs a ``byte[]``.

Do It Yourself
~~~~~~~~~~~~~~

Nothing really difficult here but note that you will have to encode
dates according to the `Date
Format <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-date-format.html>`__.

.. code:: java

    String json = "{" +
            "\"user\":\"kimchy\"," +
            "\"postDate\":\"2013-01-30\"," +
            "\"message\":\"trying out Elasticsearch\"" +
        "}";

Using Map
~~~~~~~~~

Map is a key:values pair collection. It represents very well a JSON
structure:

.. code:: java

    Map<String, Object> json = new HashMap<String, Object>();
    json.put("user","kimchy");
    json.put("postDate",new Date());
    json.put("message","trying out Elasticsearch");

Serialize your beans
~~~~~~~~~~~~~~~~~~~~

Elasticsearch already uses Jackson but shades it under
``org.elasticsearch.common.jackson`` package.So, you can add your own
Jackson version in your ``pom.xml`` file or in your classpath. See
`Jackson Download Page <http://wiki.fasterxml.com/JacksonDownload>`__.

For example:

.. code:: xml

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.1.3</version>
    </dependency>

Then, you can start serializing your beans to JSON:

.. code:: java

    import com.fasterxml.jackson.databind.*;

    // instance a json mapper
    ObjectMapper mapper = new ObjectMapper(); // create once, reuse

    // generate json
    String json = mapper.writeValueAsString(yourbeaninstance);

Use Elasticsearch helpers
~~~~~~~~~~~~~~~~~~~~~~~~~

Elasticsearch provides built-in helpers to generate JSON content.

.. code:: java

    import static org.elasticsearch.common.xcontent.XContentFactory.*;

    XContentBuilder builder = jsonBuilder()
        .startObject()
            .field("user", "kimchy")
            .field("postDate", new Date())
            .field("message", "trying out Elasticsearch")
        .endObject()

Note that you can also add arrays with ``startArray(String)`` and
``endArray()`` methods. By the way, the ``field`` methodaccepts many
object types. You can directly pass numbers, dates and even other
XContentBuilder objects.

If you need to see the generated JSON content, you can use the
``string()`` method.

.. code:: java

    String json = builder.string();

Index document
--------------

The following example indexes a JSON document into an index called
twitter, under a type called tweet, with id valued 1:

.. code:: java

    import static org.elasticsearch.common.xcontent.XContentFactory.*;

    IndexResponse response = client.prepareIndex("twitter", "tweet", "1")
            .setSource(jsonBuilder()
                        .startObject()
                            .field("user", "kimchy")
                            .field("postDate", new Date())
                            .field("message", "trying out Elasticsearch")
                        .endObject()
                      )
            .execute()
            .actionGet();

Note that you can also index your documents as JSON String and that you
don’t have to give an ID:

.. code:: java

    String json = "{" +
            "\"user\":\"kimchy\"," +
            "\"postDate\":\"2013-01-30\"," +
            "\"message\":\"trying out Elasticsearch\"" +
        "}";

    IndexResponse response = client.prepareIndex("twitter", "tweet")
            .setSource(json)
            .execute()
            .actionGet();

``IndexResponse`` object will give you a report:

.. code:: java

    // Index name
    String _index = response.getIndex();
    // Type name
    String _type = response.getType();
    // Document ID (generated or not)
    String _id = response.getId();
    // Version (if it's the first time you index this document, you will get: 1)
    long _version = response.getVersion();
    // isCreated() is true if the document is a new one, false if it has been updated
    boolean created = response.isCreated();

For more information on the index operation, check out the REST
`index <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-index_.html>`__
docs.

Operation Threading
-------------------

The index API allows one to set the threading model the operation will
be performed when the actual execution of the API is performed on the
same node (the API is executed on a shard that is allocated on the same
server).

The options are to execute the operation on a different thread, or to
execute it on the calling thread (note that the API is still
asynchronous). By default, ``operationThreaded`` is set to ``true``
which means the operation is executed on a different thread.

Get API
=======

The get API allows to get a typed JSON document from the index based on
its id. The following example gets a JSON document from an index called
twitter, under a type called tweet, with id valued 1:

.. code:: java

    GetResponse response = client.prepareGet("twitter", "tweet", "1")
            .execute()
            .actionGet();

For more information on the get operation, check out the REST
`get <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-get.html>`__
docs.

Operation Threading
-------------------

The get API allows to set the threading model the operation will be
performed when the actual execution of the API is performed on the same
node (the API is executed on a shard that is allocated on the same
server).

The options are to execute the operation on a different thread, or to
execute it on the calling thread (note that the API is still async). By
default, ``operationThreaded`` is set to ``true`` which means the
operation is executed on a different thread. Here is an example that
sets it to ``false``:

.. code:: java

    GetResponse response = client.prepareGet("twitter", "tweet", "1")
            .setOperationThreaded(false)
            .execute()
            .actionGet();

Delete API
==========

The delete API allows one to delete a typed JSON document from a
specific index based on its id. The following example deletes the JSON
document from an index called twitter, under a type called tweet, with
id valued 1:

.. code:: java

    DeleteResponse response = client.prepareDelete("twitter", "tweet", "1")
            .execute()
            .actionGet();

For more information on the delete operation, check out the `delete
API <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-delete.html>`__
docs.

Operation Threading
-------------------

The delete API allows to set the threading model the operation will be
performed when the actual execution of the API is performed on the same
node (the API is executed on a shard that is allocated on the same
server).

The options are to execute the operation on a different thread, or to
execute it on the calling thread (note that the API is still async). By
default, ``operationThreaded`` is set to ``true`` which means the
operation is executed on a different thread. Here is an example that
sets it to ``false``:

.. code:: java

    DeleteResponse response = client.prepareDelete("twitter", "tweet", "1")
            .setOperationThreaded(false)
            .execute()
            .actionGet();

Bulk API
========

The bulk API allows one to index and delete several documents in a
single request. Here is a sample usage:

.. code:: java

    import static org.elasticsearch.common.xcontent.XContentFactory.*;

    BulkRequestBuilder bulkRequest = client.prepareBulk();

    // either use client#prepare, or use Requests# to directly build index/delete requests
    bulkRequest.add(client.prepareIndex("twitter", "tweet", "1")
            .setSource(jsonBuilder()
                        .startObject()
                            .field("user", "kimchy")
                            .field("postDate", new Date())
                            .field("message", "trying out Elasticsearch")
                        .endObject()
                      )
            );

    bulkRequest.add(client.prepareIndex("twitter", "tweet", "2")
            .setSource(jsonBuilder()
                        .startObject()
                            .field("user", "kimchy")
                            .field("postDate", new Date())
                            .field("message", "another post")
                        .endObject()
                      )
            );

    BulkResponse bulkResponse = bulkRequest.execute().actionGet();
    if (bulkResponse.hasFailures()) {
        // process failures by iterating through each bulk response item
    }

**Using Bulk Processor**

The ``BulkProcessor`` class offers a simple interface to flush bulk
operations automatically based on the number or size of requests, or
after a given period.

To use it, first create a ``BulkProcessor`` instance:

.. code:: java

    import org.elasticsearch.action.bulk.BulkProcessor;

    BulkProcessor bulkProcessor = BulkProcessor.builder(
            client,  
            new BulkProcessor.Listener() {
                @Override
                public void beforeBulk(long executionId,
                                       BulkRequest request) { ... } 

                @Override
                public void afterBulk(long executionId,
                                      BulkRequest request,
                                      BulkResponse response) { ... } 

                @Override
                public void afterBulk(long executionId,
                                      BulkRequest request,
                                      Throwable failure) { ... } 
            })
            .setBulkActions(10000) 
            .setBulkSize(new ByteSizeValue(1, ByteSizeUnit.GB)) 
            .setFlushInterval(TimeValue.timeValueSeconds(5)) 
            .setConcurrentRequests(1) 
            .build();

Add your elasticsearch client

This method is called just before bulk is executed. You can for example
see the numberOfActions with ``request.numberOfActions()``

This method is called after bulk execution. You can for example check if
there was some failing requests with ``response.hasFailures()``

This method is called when the bulk failed and raised a ``Throwable``

We want to execute the bulk every 10 000 requests

We want to flush the bulk every 1gb

We want to flush the bulk every 5 seconds whatever the number of
requests

Set the number of concurrent requests. A value of 0 means that only a
single request will be allowed to be executed. A value of 1 means 1
concurrent request is allowed to be executed while accumulating new bulk
requests.

Then you can simply add your requests to the ``BulkProcessor``:

.. code:: java

    bulkProcessor.add(new IndexRequest("twitter", "tweet", "1").source(/* your doc here */));
    bulkProcessor.add(new DeleteRequest("twitter", "tweet", "2"));

By default, ``BulkProcessor``:

-  sets bulkActions to ``1000``

-  sets bulkSize to ``5mb``

-  does not set flushInterval

-  sets concurrentRequests to 1

Search API
==========

The search API allows one to execute a search query and get back search
hits that match the query. It can be executed across one or more indices
and across one or more types. The query can either be provided using the
`query Java API <#query-dsl-queries>`__ or the `filter Java
API <#query-dsl-filters>`__. The body of the search request is built
using the ``SearchSourceBuilder``. Here is an example:

.. code:: java

    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.action.search.SearchType;
    import org.elasticsearch.index.query.FilterBuilders.*;
    import org.elasticsearch.index.query.QueryBuilders.*;

.. code:: java

    SearchResponse response = client.prepareSearch("index1", "index2")
            .setTypes("type1", "type2")
            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
            .setQuery(QueryBuilders.termQuery("multi", "test"))             // Query
            .setPostFilter(FilterBuilders.rangeFilter("age").from(12).to(18))   // Filter
            .setFrom(0).setSize(60).setExplain(true)
            .execute()
            .actionGet();

Note that all parameters are optional. Here is the smallest search call
you can write:

.. code:: java

    // MatchAll on the whole cluster with all default options
    SearchResponse response = client.prepareSearch().execute().actionGet();

For more information on the search operation, check out the REST
`search <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search.html>`__
docs.

Using scrolls in Java
---------------------

Read the `scroll
documentation <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-scroll.html>`__
first!

.. code:: java

    import static org.elasticsearch.index.query.FilterBuilders.*;
    import static org.elasticsearch.index.query.QueryBuilders.*;

    QueryBuilder qb = termQuery("multi", "test");

    SearchResponse scrollResp = client.prepareSearch(test)
            .setSearchType(SearchType.SCAN)
            .setScroll(new TimeValue(60000))
            .setQuery(qb)
            .setSize(100).execute().actionGet(); //100 hits per shard will be returned for each scroll
    //Scroll until no hits are returned
    while (true) {

        for (SearchHit hit : scrollResp.getHits()) {
            //Handle the hit...
        }
        scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(600000)).execute().actionGet();
        //Break condition: No hits are returned
        if (scrollResp.getHits().getHits().length == 0) {
            break;
        }
    }

Operation Threading
-------------------

The search API allows one to set the threading model the operation will
be performed when the actual execution of the API is performed on the
same node (the API is executed on a shard that is allocated on the same
server).

There are three threading modes.The ``NO_THREADS`` mode means that the
search operation will be executed on the calling thread. The
``SINGLE_THREAD`` mode means that the search operation will be executed
on a single different thread for all local shards. The
``THREAD_PER_SHARD`` mode means that the search operation will be
executed on a different thread for each local shard.

The default mode is ``THREAD_PER_SHARD``.

MultiSearch API
---------------

See `MultiSearch API
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-multi-search.html>`__
documentation

.. code:: java

    SearchRequestBuilder srb1 = node.client()
        .prepareSearch().setQuery(QueryBuilders.queryString("elasticsearch")).setSize(1);
    SearchRequestBuilder srb2 = node.client()
        .prepareSearch().setQuery(QueryBuilders.matchQuery("name", "kimchy")).setSize(1);

    MultiSearchResponse sr = node.client().prepareMultiSearch()
            .add(srb1)
            .add(srb2)
            .execute().actionGet();

    // You will get all individual responses from MultiSearchResponse#getResponses()
    long nbHits = 0;
    for (MultiSearchResponse.Item item : sr.getResponses()) {
        SearchResponse response = item.getResponse();
        nbHits += response.getHits().getTotalHits();
    }

Using Facets
------------

The following code shows how to add two facets within your search:

.. code:: java

    SearchResponse sr = node.client().prepareSearch()
        .setQuery(QueryBuilders.matchAllQuery())
        .addFacet(FacetBuilders.termsFacet("f1").field("field"))
        .addFacet(FacetBuilders.dateHistogramFacet("f2").field("birth").interval("year"))
        .execute().actionGet();

    // Get your facet results
    TermsFacet f1 = (TermsFacet) sr.getFacets().facetsAsMap().get("f1");
    DateHistogramFacet f2 = (DateHistogramFacet) sr.getFacets().facetsAsMap().get("f2");

See `Facets Java API <#java-facets>`__ documentation for details.

Count API
=========

The count API allows one to easily execute a query and get the number of
matches for that query. It can be executed across one or more indices
and across one or more types. The query can be provided using the `Query
DSL <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html>`__.

.. code:: java

    import static org.elasticsearch.index.query.FilterBuilders.*;
    import static org.elasticsearch.index.query.QueryBuilders.*;

    CountResponse response = client.prepareCount("test")
            .setQuery(termQuery("_type", "type1"))
            .execute()
            .actionGet();

For more information on the count operation, check out the REST
`count <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-count.html>`__
docs.

Operation Threading
-------------------

The count API allows one to set the threading model the operation will
be performed when the actual execution of the API is performed on the
same node (the API is executed on a shard that is allocated on the same
server).

There are three threading modes.The ``NO_THREADS`` mode means that the
count operation will be executed on the calling thread. The
``SINGLE_THREAD`` mode means that the count operation will be executed
on a single different thread for all local shards. The
``THREAD_PER_SHARD`` mode means that the count operation will be
executed on a different thread for each local shard.

The default mode is ``SINGLE_THREAD``.

Delete By Query API
===================

The delete by query API allows one to delete documents from one or more
indices and one or more types based on a `query <#query-dsl-queries>`__.
Here is an example:

.. code:: java

    import static org.elasticsearch.index.query.FilterBuilders.*;
    import static org.elasticsearch.index.query.QueryBuilders.*;

    DeleteByQueryResponse response = client.prepareDeleteByQuery("test")
            .setQuery(termQuery("_type", "type1"))
            .execute()
            .actionGet();

For more information on the delete by query operation, check out the
`delete\_by\_query
API <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-delete-by-query.html>`__
docs.

Facets
======

Elasticsearch provides a full Java API to play with facets. See the
`Facets
guide <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets.html>`__.

Use the factory for facet builders (``FacetBuilders``) and add each
facet you want to compute when querying and add it to your search
request:

.. code:: java

    SearchResponse sr = node.client().prepareSearch()
            .setQuery( /* your query */ )
            .addFacet( /* add a facet */ )
            .execute().actionGet();

Note that you can add more than one facet. See `Search Java
API <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-search.html>`__
for details.

To build facet requests, use ``FacetBuilders`` helpers. Just import them
in your class:

.. code:: java

    import org.elasticsearch.search.facet.FacetBuilders.*;

Facets
------

Terms Facet
~~~~~~~~~~~

Here is how you can use `Terms
Facet <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-terms-facet.html>`__
with Java API.

Prepare facet request
^^^^^^^^^^^^^^^^^^^^^

Here is an example on how to create the facet request:

.. code:: java

    FacetBuilders.termsFacet("f")
        .field("brand")
        .size(10);

Use facet response
^^^^^^^^^^^^^^^^^^

Import Facet definition classes:

.. code:: java

    import org.elasticsearch.search.facet.terms.*;

.. code:: java

    // sr is here your SearchResponse object
    TermsFacet f = (TermsFacet) sr.getFacets().facetsAsMap().get("f");

    f.getTotalCount();      // Total terms doc count
    f.getOtherCount();      // Not shown terms doc count
    f.getMissingCount();    // Without term doc count

    // For each entry
    for (TermsFacet.Entry entry : f) {
        entry.getTerm();    // Term
        entry.getCount();   // Doc count
    }

Range Facet
~~~~~~~~~~~

Here is how you can use `Range
Facet <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-range-facet.html>`__
with Java API.

Prepare facet request
^^^^^^^^^^^^^^^^^^^^^

Here is an example on how to create the facet request:

.. code:: java

    FacetBuilders.rangeFacet("f")
        .field("price")         // Field to compute on
        .addUnboundedFrom(3)    // from -infinity to 3 (excluded)
        .addRange(3, 6)         // from 3 to 6 (excluded)
        .addUnboundedTo(6);     // from 6 to +infinity

Use facet response
^^^^^^^^^^^^^^^^^^

Import Facet definition classes:

.. code:: java

    import org.elasticsearch.search.facet.range.*;

.. code:: java

    // sr is here your SearchResponse object
    RangeFacet f = (RangeFacet) sr.getFacets().facetsAsMap().get("f");

    // For each entry
    for (RangeFacet.Entry entry : f) {
        entry.getFrom();    // Range from requested
        entry.getTo();      // Range to requested
        entry.getCount();   // Doc count
        entry.getMin();     // Min value
        entry.getMax();     // Max value
        entry.getMean();    // Mean
        entry.getTotal();   // Sum of values
    }

Histogram Facet
~~~~~~~~~~~~~~~

Here is how you can use `Histogram
Facet <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-histogram-facet.html>`__
with Java API.

Prepare facet request
^^^^^^^^^^^^^^^^^^^^^

Here is an example on how to create the facet request:

.. code:: java

    HistogramFacetBuilder facet = FacetBuilders.histogramFacet("f")
        .field("price")
        .interval(1);

Use facet response
^^^^^^^^^^^^^^^^^^

Import Facet definition classes:

.. code:: java

    import org.elasticsearch.search.facet.histogram.*;

.. code:: java

    // sr is here your SearchResponse object
    HistogramFacet f = (HistogramFacet) sr.getFacets().facetsAsMap().get("f");

    // For each entry
    for (HistogramFacet.Entry entry : f) {
        entry.getKey();     // Key (X-Axis)
        entry.getCount();   // Doc count (Y-Axis)
    }

Date Histogram Facet
~~~~~~~~~~~~~~~~~~~~

Here is how you can use `Date Histogram
Facet <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-date-histogram-facet.html>`__
with Java API.

Prepare facet request
^^^^^^^^^^^^^^^^^^^^^

Here is an example on how to create the facet request:

.. code:: java

    FacetBuilders.dateHistogramFacet("f")
        .field("date")      // Your date field
        .interval("year");  // You can also use "quarter", "month", "week", "day",
                            // "hour" and "minute" or notation like "1.5h" or "2w"

Use facet response
^^^^^^^^^^^^^^^^^^

Import Facet definition classes:

.. code:: java

    import org.elasticsearch.search.facet.datehistogram.*;

.. code:: java

    // sr is here your SearchResponse object
    DateHistogramFacet f = (DateHistogramFacet) sr.getFacets().facetsAsMap().get("f");

    // For each entry
    for (DateHistogramFacet.Entry entry : f) {
        entry.getTime();    // Date in ms since epoch (X-Axis)
        entry.getCount();   // Doc count (Y-Axis)
    }

Filter Facet (not facet filter)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Here is how you can use `Filter
Facet <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-filter-facet.html>`__
with Java API.

If you are looking on how to apply a filter to a facet, have a look at
`facet filter <#facet-filter>`__ using Java API.

Prepare facet request
^^^^^^^^^^^^^^^^^^^^^

Here is an example on how to create the facet request:

.. code:: java

    FacetBuilders.filterFacet("f",
        FilterBuilders.termFilter("brand", "heineken"));    // Your Filter here

See `Filters <#query-dsl-filters>`__ to learn how to build filters using
Java.

Use facet response
^^^^^^^^^^^^^^^^^^

Import Facet definition classes:

.. code:: java

    import org.elasticsearch.search.facet.filter.*;

.. code:: java

    // sr is here your SearchResponse object
    FilterFacet f = (FilterFacet) sr.getFacets().facetsAsMap().get("f");

    f.getCount();   // Number of docs that matched

Query Facet
~~~~~~~~~~~

Here is how you can use `Query
Facet <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-query-facet.html>`__
with Java API.

Prepare facet request
^^^^^^^^^^^^^^^^^^^^^

Here is an example on how to create the facet request:

.. code:: java

    FacetBuilders.queryFacet("f",
        QueryBuilders.matchQuery("brand", "heineken"));

Use facet response
^^^^^^^^^^^^^^^^^^

Import Facet definition classes:

.. code:: java

    import org.elasticsearch.search.facet.query.*;

.. code:: java

    // sr is here your SearchResponse object
    QueryFacet f = (QueryFacet) sr.getFacets().facetsAsMap().get("f");

    f.getCount();   // Number of docs that matched

See `Queries <#query-dsl-queries>`__ to learn how to build queries using
Java.

Statistical
~~~~~~~~~~~

Here is how you can use the `Statistical
Facet <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-statistical-facet.html>`__
with Java API.

Prepare facet request
^^^^^^^^^^^^^^^^^^^^^

Here is an example on how to create the facet request:

.. code:: java

    FacetBuilders.statisticalFacet("f")
       .field("price");

Use facet response
^^^^^^^^^^^^^^^^^^

Import Facet definition classes:

.. code:: java

    import org.elasticsearch.search.facet.statistical.*;

.. code:: java

    // sr is here your SearchResponse object
    StatisticalFacet f = (StatisticalFacet) sr.getFacets().facetsAsMap().get("f");

    f.getCount();           // Doc count
    f.getMin();             // Min value
    f.getMax();             // Max value
    f.getMean();            // Mean
    f.getTotal();           // Sum of values
    f.getStdDeviation();    // Standard Deviation
    f.getSumOfSquares();    // Sum of Squares
    f.getVariance();        // Variance

Terms Stats Facet
~~~~~~~~~~~~~~~~~

Here is how you can use the `Terms Stats
Facet <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-terms-stats-facet.html>`__
with Java API.

Prepare facet request
^^^^^^^^^^^^^^^^^^^^^

Here is an example on how to create the facet request:

.. code:: java

    FacetBuilders.termsStatsFacet("f")
        .keyField("brand")
        .valueField("price");

Use facet response
^^^^^^^^^^^^^^^^^^

Import Facet definition classes:

.. code:: java

    import org.elasticsearch.search.facet.termsstats.*;

.. code:: java

    // sr is here your SearchResponse object
    TermsStatsFacet f = (TermsStatsFacet) sr.getFacets().facetsAsMap().get("f");
    f.getTotalCount();      // Total terms doc count
    f.getOtherCount();      // Not shown terms doc count
    f.getMissingCount();    // Without term doc count

    // For each entry
    for (TermsStatsFacet.Entry entry : f) {
        entry.getTerm();            // Term
        entry.getCount();           // Doc count
        entry.getMin();             // Min value
        entry.getMax();             // Max value
        entry.getMean();            // Mean
        entry.getTotal();           // Sum of values
    }

Geo Distance Facet
~~~~~~~~~~~~~~~~~~

Here is how you can use the `Geo Distance
Facet <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-geo-distance-facet.html>`__
with Java API.

Prepare facet request
^^^^^^^^^^^^^^^^^^^^^

Here is an example on how to create the facet request:

.. code:: java

    FacetBuilders.geoDistanceFacet("f")
        .field("pin.location")              // Field containing coordinates we want to compare with
        .point(40, -70)                     // Point from where we start (0)
        .addUnboundedFrom(10)               // 0 to 10 km (excluded)
        .addRange(10, 20)                   // 10 to 20 km (excluded)
        .addRange(20, 100)                  // 20 to 100 km (excluded)
        .addUnboundedTo(100)                // from 100 km to infinity (and beyond ;-) )
        .unit(DistanceUnit.KILOMETERS);     // All distances are in kilometers. Can be MILES

Use facet response
^^^^^^^^^^^^^^^^^^

Import Facet definition classes:

.. code:: java

    import org.elasticsearch.search.facet.geodistance.*;

.. code:: java

    // sr is here your SearchResponse object
    GeoDistanceFacet f = (GeoDistanceFacet) sr.getFacets().facetsAsMap().get("f");

    // For each entry
    for (GeoDistanceFacet.Entry entry : f) {
        entry.getFrom();            // Distance from requested
        entry.getTo();              // Distance to requested
        entry.getCount();           // Doc count
        entry.getMin();             // Min value
        entry.getMax();             // Max value
        entry.getTotal();           // Sum of values
        entry.getMean();            // Mean
    }

Facet filters (not Filter Facet)
--------------------------------

By default, facets are applied on the query resultset whatever filters
exists or are.

If you need to compute facets with the same filters or even with other
filters, you can add the filter to any facet using
``AbstractFacetBuilder#facetFilter(FilterBuilder)`` method:

.. code:: java

    FacetBuilders
        .termsFacet("f").field("brand") // Your facet
        .facetFilter( // Your filter here
            FilterBuilders.termFilter("colour", "pale")
        );

For example, you can reuse the same filter you created for your query:

.. code:: java

    // A common filter
    FilterBuilder filter = FilterBuilders.termFilter("colour", "pale");

    TermsFacetBuilder facet = FacetBuilders.termsFacet("f")
        .field("brand")
        .facetFilter(filter);                           // We apply it to the facet

    SearchResponse sr = node.client().prepareSearch()
        .setQuery(QueryBuilders.matchAllQuery())
        .setFilter(filter)                              // We apply it to the query
        .addFacet(facet)
        .execute().actionGet();

See documentation on how to build `Filters <#query-dsl-filters>`__.

Scope
-----

By default, facets are computed within the query resultset. But, you can
compute facets from all documents in the index whatever the query is,
using ``global`` parameter:

.. code:: java

    TermsFacetBuilder facet = FacetBuilders.termsFacet("f")
        .field("brand")
        .global(true);

Percolate API
=============

The percolator allows one to register queries against an index, and then
send ``percolate`` requests which include a doc, getting back the
queries that match on that doc out of the set of registered queries.

Read the main
`percolate <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-percolate.html>`__
documentation before reading this guide.

.. code:: java

    //This is the query we're registering in the percolator
    QueryBuilder qb = termQuery("content", "amazing");

    //Index the query = register it in the percolator
    client.prepareIndex("myIndexName", ".percolator", "myDesignatedQueryName")
        .setSource(jsonBuilder()
            .startObject()
                .field("query", qb) // Register the query
            .endObject())
        .setRefresh(true) // Needed when the query shall be available immediately
        .execute().actionGet();

This indexes the above term query under the name
**myDesignatedQueryName**.

In order to check a document against the registered queries, use this
code:

.. code:: java

    //Build a document to check against the percolator
    XContentBuilder docBuilder = XContentFactory.jsonBuilder().startObject();
    docBuilder.field("doc").startObject(); //This is needed to designate the document
    docBuilder.field("content", "This is amazing!");
    docBuilder.endObject(); //End of the doc field
    docBuilder.endObject(); //End of the JSON root object
    //Percolate
    PercolateResponse response = client.preparePercolate()
                            .setIndices("myIndexName")
                            .setDocumentType("myDocumentType")
                            .setSource(docBuilder).execute().actionGet();
    //Iterate over the results
    for(PercolateResponse.Match match : response) {
        //Handle the result which is the name of
        //the query in the percolator
    }

Query DSL - Queries
===================

elasticsearch provides a full Java query dsl in a similar manner to the
REST `Query
DSL <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html>`__.
The factory for query builders is ``QueryBuilders``. Once your query is
ready, you can use the `Search API <#search>`__.

See also how to build `Filters <#query-dsl-filters>`__

To use ``QueryBuilders`` or ``FilterBuilders`` just import them in your
class:

.. code:: java

    import static org.elasticsearch.index.query.QueryBuilders.*;
    import static org.elasticsearch.index.query.FilterBuilders.*;

Note that you can easily print (aka debug) JSON generated queries using
``toString()`` method on ``QueryBuilder`` object.

The ``QueryBuilder`` can then be used with any API that accepts a query,
such as ``count`` and ``search``.

Match Query
-----------

See `Match
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-match-query.html>`__

.. code:: java

    QueryBuilder qb = matchQuery(
        "name",                  
        "kimchy elasticsearch"   
    );

field

text

MultiMatch Query
----------------

See `MultiMatch
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html>`__

.. code:: java

    QueryBuilder qb = multiMatchQuery(
        "kimchy elasticsearch", 
        "user", "message"       
    );

text

fields

Boolean Query
-------------

See `Boolean
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html>`__

.. code:: java

    QueryBuilder qb = boolQuery()
        .must(termQuery("content", "test1"))    
        .must(termQuery("content", "test4"))    
        .mustNot(termQuery("content", "test2")) 
        .should(termQuery("content", "test3")); 

must query

must not query

should query

Boosting Query
--------------

See `Boosting
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-boosting-query.html>`__

.. code:: java

    QueryBuilder qb = boostingQuery()
        .positive(termQuery("name","kimchy"))   
        .negative(termQuery("name","dadoonet")) 
        .negativeBoost(0.2f);                   

query that will promote documents

query that will demote documents

negative boost

IDs Query
---------

See `IDs
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-ids-query.html>`__

.. code:: java

    QueryBuilder qb = idsQuery().ids("1", "2"); 

document ids

Constant Score Query
--------------------

See `Constant Score
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-constant-score-query.html>`__

.. code:: java

    QueryBuilder qb = constantScoreQuery(
            termFilter("name","kimchy")     
        )
        .boost(2.0f);                       

you can use a filter

filter score

.. code:: java

    QueryBuilder qb = constantScoreQuery(
            termQuery("name","kimchy")      
        )
        .boost(2.0f);                       

you can use a query

query score

Disjunction Max Query
---------------------

See `Disjunction Max
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-dis-max-query.html>`__

.. code:: java

    QueryBuilder qb = disMaxQuery()
        .add(termQuery("name","kimchy"))        
        .add(termQuery("name","elasticsearch")) 
        .boost(1.2f)                            
        .tieBreaker(0.7f);                      

add your queries

add your queries

boost factor

tie breaker

Fuzzy Like This (Field) Query (flt and flt\_field)
--------------------------------------------------

See: \* `Fuzzy Like This
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-flt-query.html>`__
\* `Fuzzy Like This Field
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-flt-field-query.html>`__

.. code:: java

    QueryBuilder qb = fuzzyLikeThisQuery("name.first", "name.last") 
        .likeText("text like this one")                             
        .maxQueryTerms(12);                                         

fields

text

max num of Terms in generated queries

.. code:: java

    QueryBuilder qb = fuzzyLikeThisFieldQuery("name.first")         
                    .likeText("text like this one")                 
                    .maxQueryTerms(12);                             

field

text

max num of Terms in generated queries

FuzzyQuery
----------

See `Fuzzy
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-fuzzy-query.html>`__

.. code:: java

    QueryBuilder qb = fuzzyQuery(
        "name",     
        "kimzhy"    
    );

field

text

Has Child / Has Parent
----------------------

See: \* `Has Child
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-child-query.html>`__
\* `Has
Parent <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html>`__

.. code:: java

    // Has Child
    QueryBuilder qb = hasChildQuery(
        "blog_tag",                     
        termQuery("tag","something")    
    );

child type to query against

query (could be also a filter)

.. code:: java

    QueryBuilder qb = hasParentQuery(
        "blog",                         
        termQuery("tag","something")    
    );

parent type to query against

query (could be also a filter)

MatchAll Query
--------------

See `Match All
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-match-all-query.html>`__

.. code:: java

    QueryBuilder qb = matchAllQuery();

More Like This (Field) Query (mlt and mlt\_field)
-------------------------------------------------

See: \* `More Like This
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html>`__

.. code:: java

    // mlt Query
    QueryBuilder qb = moreLikeThisQuery("name.first", "name.last")  
        .likeText("text like this one")                             
        .minTermFreq(1)                                             
        .maxQueryTerms(12);                                         

fields

text

ignore threshold

max num of Terms in generated queries

Prefix Query
------------

See `Prefix
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-prefix-query.html>`__

.. code:: java

    QueryBuilder qb = prefixQuery(
        "brand",    
        "heine"     
    );

field

prefix

QueryString Query
-----------------

See `QueryString
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html>`__

.. code:: java

    QueryBuilder qb = queryString("+kimchy -elasticsearch");    

text

Range Query
-----------

See `Range
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-range-query.html>`__

.. code:: java

    QueryBuilder qb = rangeQuery("price")   
        .from(5)                            
        .to(10)                             
        .includeLower(true)                 
        .includeUpper(false);               

field

from

to

include lower value means that ``from`` is ``gt`` when ``false`` or
``gte`` when ``true``

include upper value means that ``to`` is ``lt`` when ``false`` or
``lte`` when ``true``

Span Queries (first, near, not, or, term)
-----------------------------------------

See: \* `Span Term
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-term-query.html>`__
\* `Span First
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-first-query.html>`__
\* `Span Near
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-near-query.html>`__
\* `Span Not
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-not-query.html>`__
\* `Span Or
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-span-or-query.html>`__

.. code:: java

    // Span Term
    QueryBuilder qb = spanTermQuery(
        "user",                                     
        "kimchy"                                    
    );

field

value

.. code:: java

    // Span First
    QueryBuilder qb = spanFirstQuery(
        spanTermQuery("user", "kimchy"),            
        3                                           
    );

query

max end position

.. code:: java

    // Span Near
    QueryBuilder qb = spanNearQuery()
        .clause(spanTermQuery("field","value1"))    
        .clause(spanTermQuery("field","value2"))    
        .clause(spanTermQuery("field","value3"))    
        .slop(12)                                   
        .inOrder(false)                             
        .collectPayloads(false);                    

span term queries

slop factor: the maximum number of intervening unmatched positions

whether matches are required to be in-order

collect payloads or not

.. code:: java

    // Span Not
    QueryBuilder qb = spanNotQuery()
        .include(spanTermQuery("field","value1"))   
        .exclude(spanTermQuery("field","value2"));  

span query whose matches are filtered

span query whose matches must not overlap those returned

.. code:: java

    // Span Or
    QueryBuilder qb = spanOrQuery()
        .clause(spanTermQuery("field","value1"))    
        .clause(spanTermQuery("field","value2"))    
        .clause(spanTermQuery("field","value3"));   

span term queries

Term Query
----------

See `Term
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-term-query.html>`__

.. code:: java

    QueryBuilder qb = termQuery(
        "name",     
        "kimchy");  

field

value

Terms Query
-----------

See `Terms
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html>`__

.. code:: java

    QueryBuilder qb = termsQuery("tags",    
        "blue", "pill")                 
        .minimumMatch(1);               

field

values

how many terms must match at least

Top Children Query
------------------

See `Top Children
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-top-children-query.html>`__

.. code:: java

    QueryBuilder qb = topChildrenQuery(
            "blog_tag",                   
            termQuery("tag", "something") 
        )
        .score("max")                     
        .factor(5)                        
        .incrementalFactor(2);            

field

query

``max``, ``sum`` or ``avg``

how many hits are asked for in the first child query run (defaults to 5)

if not enough parents are found, and there are still more child docs to
query, then the child search hits are expanded by multiplying by the
incremental\_factor (defaults to 2).

Wildcard Query
--------------

See `Wildcard
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html>`__

.. code:: java

    QueryBuilder qb = wildcardQuery("user", "k?mc*");

Nested Query
------------

See `Nested
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html>`__

.. code:: java

    QueryBuilder qb = nestedQuery(
            "obj1",               
            boolQuery()           
                    .must(matchQuery("obj1.name", "blue"))
                    .must(rangeQuery("obj1.count").gt(5))
        )
        .scoreMode("avg");        

path to nested document

your query. Any fields referenced inside the query must use the complete
path (fully qualified).

score mode could be ``max``, ``total``, ``avg`` (default) or ``none``

Indices Query
-------------

See `Indices
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-indices-query.html>`__

.. code:: java

    // Using another query when no match for the main one
    QueryBuilder qb = indicesQuery(
            termQuery("tag", "wow"),            
            "index1", "index2"                  
        )
        .noMatchQuery(termQuery("tag", "kow")); 

query to be executed on selected indices

selected indices

query to be executed on non matching indices

.. code:: java

    // Using all (match all) or none (match no documents)
    QueryBuilder qb = indicesQuery(
            termQuery("tag", "wow"),            
            "index1", "index2"                  
        )
        .noMatchQuery("all");                   

query to be executed on selected indices

selected indices

``none`` (to match no documents), and ``all`` (to match all documents).
Defaults to ``all``.

GeoShape Query
--------------

See `GeoShape
Query <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-query.html>`__

Note: the ``geo_shape`` type uses ``Spatial4J`` and ``JTS``, both of
which are optional dependencies. Consequently you must add ``Spatial4J``
and ``JTS`` to your classpath in order to use this type:

.. code:: xml

    <dependency>
        <groupId>com.spatial4j</groupId>
        <artifactId>spatial4j</artifactId>
        <version>0.4.1</version>                        
    </dependency>

    <dependency>
        <groupId>com.vividsolutions</groupId>
        <artifactId>jts</artifactId>
        <version>1.13</version>                         
        <exclusions>
            <exclusion>
                <groupId>xerces</groupId>
                <artifactId>xercesImpl</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

check for updates in `Maven
Central <http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.spatial4j%22%20AND%20a%3A%22spatial4j%22>`__

check for updates in `Maven
Central <http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.vividsolutions%22%20AND%20a%3A%22jts%22>`__

.. code:: java

    // Import Spatial4J shapes
    import com.spatial4j.core.context.SpatialContext;
    import com.spatial4j.core.shape.Shape;
    import com.spatial4j.core.shape.impl.RectangleImpl;

    // Also import ShapeRelation
    import org.elasticsearch.common.geo.ShapeRelation;

.. code:: java

    // Shape within another
    QueryBuilder qb = geoShapeQuery(
            "location",                                     
            new RectangleImpl(0,10,0,10,SpatialContext.GEO) 
        )
        .relation(ShapeRelation.WITHIN);                    

field

shape

relation

.. code:: java

    // Intersect shapes
    QueryBuilder qb = geoShapeQuery(
            "location",                                     
            new PointImpl(0, 0, SpatialContext.GEO)         
        )
        .relation(ShapeRelation.INTERSECTS);                

field

shape

relation

.. code:: java

    // Using pre-indexed shapes
    QueryBuilder qb = geoShapeQuery(
            "location",                                     
            "New Zealand",                                  
            "countries")                                    
        .relation(ShapeRelation.DISJOINT);                  

field

indexed shape id

index type of the indexed shapes

relation

Query DSL - Filters
===================

elasticsearch provides a full Java query dsl in a similar manner to the
REST `Query
DSL <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html>`__.
The factory for filter builders is ``FilterBuilders``.

Once your query is ready, you can use the `Search API <#search>`__.

See also how to build `Queries <#query-dsl-queries>`__.

To use ``QueryBuilders`` or ``FilterBuilders`` just import them in your
class:

.. code:: java

    import static org.elasticsearch.index.query.QueryBuilders.*;
    import static org.elasticsearch.index.query.FilterBuilders.*;

Note that you can easily print (aka debug) JSON generated queries using
``toString()`` method on ``FilterBuilder`` object.

And Filter
----------

See `And
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-and-filter.html>`__

.. code:: java

    FilterBuilder filter = andFilter(
        rangeFilter("postDate").from("2010-03-01").to("2010-04-01"),    
        prefixFilter("name.second", "ba"));                             

filters

Note that you can cache the result using
``AndFilterBuilder#cache(boolean)`` method. See ?.

Bool Filter
-----------

See `Bool
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html>`__

.. code:: java

    FilterBuilder filter = boolFilter()
        .must(termFilter("tag", "wow"))                     
        .mustNot(rangeFilter("age").from("10").to("20"))    
        .should(termFilter("tag", "sometag"))               
        .should(termFilter("tag", "sometagtag"));           

must filter

must not filter

should filter

Note that you can cache the result using
``BoolFilterBuilder#cache(boolean)`` method. See ?.

Exists Filter
-------------

See `Exists
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-exists-filter.html>`__.

.. code:: java

    FilterBuilder filter = existsFilter("user");    

field

Ids Filter
----------

See `IDs
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-ids-filter.html>`__

.. code:: java

    FilterBuilder filter = idsFilter("my_type", "type2")
        .addIds("1", "4", "100");

    FilterBuilder filter = idsFilter() 
        .addIds("1", "4", "100");

type is optional

Limit Filter
------------

See `Limit
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-limit-filter.html>`__

.. code:: java

    FilterBuilder filter = limitFilter(100);    

number of documents per shard

Type Filter
-----------

See `Type
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-type-filter.html>`__

.. code:: java

    FilterBuilder filter = typeFilter("my_type");   

type

Geo Bounding Box Filter
-----------------------

See `Geo Bounding Box
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-bounding-box-filter.html>`__

.. code:: java

    FilterBuilder filter = geoBoundingBoxFilter("pin.location") 
        .topLeft(40.73, -74.1)                                  
        .bottomRight(40.717, -73.99);                           

field

bounding box top left point

bounding box bottom right point

Note that you can cache the result using
``GeoBoundingBoxFilterBuilder#cache(boolean)`` method. See ?.

GeoDistance Filter
------------------

See `Geo Distance
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-filter.html>`__

.. code:: java

    FilterBuilder filter = geoDistanceFilter("pin.location")    
        .point(40, -70)                                         
        .distance(200, DistanceUnit.KILOMETERS)                 
        .optimizeBbox("memory")                                 
        .geoDistance(GeoDistance.ARC);                          

field

center point

distance from center point

optimize bounding box: ``memory``, ``indexed`` or ``none``

distance computation mode: ``GeoDistance.SLOPPY_ARC`` (default),
``GeoDistance.ARC`` (slighly more precise but significantly slower) or
``GeoDistance.PLANE`` (faster, but inaccurate on long distances and
close to the poles)

Note that you can cache the result using
``GeoDistanceFilterBuilder#cache(boolean)`` method. See ?.

Geo Distance Range Filter
-------------------------

See `Geo Distance Range
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-range-filter.html>`__

.. code:: java

    FilterBuilder filter = geoDistanceRangeFilter("pin.location")   
        .point(40, -70)                                             
        .from("200km")                                              
        .to("400km")                                                
        .includeLower(true)                                         
        .includeUpper(false)                                        
        .optimizeBbox("memory")                                     
        .geoDistance(GeoDistance.ARC);                              

field

center point

starting distance from center point

ending distance from center point

include lower value means that ``from`` is ``gt`` when ``false`` or
``gte`` when ``true``

include upper value means that ``to`` is ``lt`` when ``false`` or
``lte`` when ``true``

optimize bounding box: ``memory``, ``indexed`` or ``none``

distance computation mode: ``GeoDistance.SLOPPY_ARC`` (default),
``GeoDistance.ARC`` (slighly more precise but significantly slower) or
``GeoDistance.PLANE`` (faster, but inaccurate on long distances and
close to the poles)

Note that you can cache the result using
``GeoDistanceRangeFilterBuilder#cache(boolean)`` method. See ?.

Geo Polygon Filter
------------------

See `Geo Polygon
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-polygon-filter.html>`__

.. code:: java

    FilterBuilder filter = geoPolygonFilter("pin.location") 
        .addPoint(40, -70)                                  
        .addPoint(30, -80)                                  
        .addPoint(20, -90);                                 

field

add your polygon of points a document should fall within

Note that you can cache the result using
``GeoPolygonFilterBuilder#cache(boolean)`` method. See ?.

Geo Shape Filter
----------------

See `Geo Shape
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html>`__

Note: the ``geo_shape`` type uses ``Spatial4J`` and ``JTS``, both of
which are optional dependencies. Consequently you must add ``Spatial4J``
and ``JTS`` to your classpath in order to use this type:

.. code:: xml

    <dependency>
        <groupId>com.spatial4j</groupId>
        <artifactId>spatial4j</artifactId>
        <version>0.4.1</version>                        
    </dependency>

    <dependency>
        <groupId>com.vividsolutions</groupId>
        <artifactId>jts</artifactId>
        <version>1.13</version>                         
        <exclusions>
            <exclusion>
                <groupId>xerces</groupId>
                <artifactId>xercesImpl</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

check for updates in `Maven
Central <http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.spatial4j%22%20AND%20a%3A%22spatial4j%22>`__

check for updates in `Maven
Central <http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.vividsolutions%22%20AND%20a%3A%22jts%22>`__

.. code:: java

    // Import Spatial4J shapes
    import com.spatial4j.core.context.SpatialContext;
    import com.spatial4j.core.shape.Shape;
    import com.spatial4j.core.shape.impl.RectangleImpl;

    // Also import ShapeRelation
    import org.elasticsearch.common.geo.ShapeRelation;

.. code:: java

    // Shape within another
    FilterBuilder filter = geoShapeFilter(
            "location",                                     
            new RectangleImpl(0,10,0,10,SpatialContext.GEO) 
        )
        .relation(ShapeRelation.WITHIN);                    

field

shape

relation

.. code:: java

    // Intersect shapes
    FilterBuilder filter = geoShapeFilter(
            "location",                                     
            new PointImpl(0, 0, SpatialContext.GEO)         
        )
        .relation(ShapeRelation.INTERSECTS);                

field

shape

relation

.. code:: java

    // Using pre-indexed shapes
    FilterBuilder filter = geoShapeFilter(
            "location",                                     
            "New Zealand",                                  
            "countries")                                    
        .relation(ShapeRelation.DISJOINT);                  

field

indexed shape id

index type of the indexed shapes

relation

Has Child / Has Parent Filters
------------------------------

See: \* `Has Child
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-child-filter.html>`__
\* `Has Parent
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-parent-filter.html>`__

.. code:: java

    // Has Child
    QueryBuilder qb = hasChildFilter(
        "blog_tag",                     
        termFilter("tag","something")   
    );

child type to query against

filter (could be also a query)

.. code:: java

    // Has Parent
    QueryBuilder qb = hasParentFilter(
        "blog",                         
        termFilter("tag","something")   
    );

parent type to query against

filter (could be also a query)

Match All Filter
----------------

See `Match All
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-match-all-filter.html>`__

.. code:: java

    FilterBuilder filter = matchAllFilter();

Missing Filter
--------------

See `Missing
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-missing-filter.html>`__

.. code:: java

    FilterBuilder filter = missingFilter("user")    
        .existence(true)                            
        .nullValue(true);                           

field

find missing field that doesn’t exist

find missing field with an explicit ``null`` value

Not Filter
----------

See `Not
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-not-filter.html>`__

.. code:: java

    FilterBuilder filter = notFilter(
        rangeFilter("price").from("1").to("2")  
    );

filter

Or Filter
---------

See `Or
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-or-filter.html>`__

.. code:: java

    FilterBuilder filter = orFilter(
            termFilter("name.second", "banon"), 
            termFilter("name.nick", "kimchy")   
        );

filters

Note that you can cache the result using
``OrFilterBuilder#cache(boolean)`` method. See ?.

Prefix Filter
-------------

See `Prefix
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-prefix-filter.html>`__

.. code:: java

    FilterBuilder filter = prefixFilter(
        "user", 
        "ki"    
    );

field

prefix

Note that you can cache the result using
``PrefixFilterBuilder#cache(boolean)`` method. See ?.

Query Filter
------------

See `Query
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-filter.html>`__

.. code:: java

    FilterBuilder filter = queryFilter(
            queryString("this AND that OR thus")    
        );

query you want to wrap as a filter

Note that you can cache the result using
``QueryFilterBuilder#cache(boolean)`` method. See ?.

Range Filter
------------

See `Range
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-range-filter.html>`__

.. code:: java

    FilterBuilder filter = rangeFilter("age")   
        .from("10")                             
        .to("20")                               
        .includeLower(true)                     
        .includeUpper(false);                   

field

from

to

include lower value means that ``from`` is ``gt`` when ``false`` or
``gte`` when ``true``

include upper value means that ``to`` is ``lt`` when ``false`` or
``lte`` when ``true``

.. code:: java

    // A simplified form using gte, gt, lt or lte
    FilterBuilder filter = rangeFilter("age")   
        .gte("10")                              
        .lt("20");                              

field

set ``from`` to 10 and ``includeLower`` to true

set ``to`` to 20 and ``includeUpper`` to false

Note that you can ask not to cache the result using
``RangeFilterBuilder#cache(boolean)`` method. See ?.

Script Filter
-------------

See `Script
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-script-filter.html>`__

.. code:: java

    FilterBuilder filter = scriptFilter(
            "doc['age'].value > param1" 
        ).addParam("param1", 10);       

script to execute

parameters

Note that you can cache the result using
``ScriptFilterBuilder#cache(boolean)`` method. See ?.

Term Filter
-----------

See `Term
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-term-filter.html>`__

.. code:: java

    FilterBuilder filter = termFilter(
        "user",     
        "kimchy"    
    );

field

value

Note that you can ask not to cache the result using
``TermFilterBuilder#cache(boolean)`` method. See ?.

Terms Filter
------------

See `Terms
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-terms-filter.html>`__

.. code:: java

    FilterBuilder filter = termsFilter(
            "user",             
            "kimchy",           
            "elasticsearch"     
        )
        .execution("plain");    

field

terms

execution mode: could be ``plain``, ``fielddata``, ``bool``, ``and``,
``or``, ``bool_nocache``, ``and_nocache`` or ``or_nocache``

Note that you can ask not to cache the result using
``TermsFilterBuilder#cache(boolean)`` method. See ?.

Nested Filter
-------------

See `Nested
Filter <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-nested-filter.html>`__

.. code:: java

    FilterBuilder filter = nestedFilter("obj1",                     
        boolFilter()                                                
            .must(termFilter("obj1.name", "blue"))
            .must(rangeFilter("obj1.count").gt(5))
        );

path to nested document

filter

Note that you can ask not to cache the result using
``NestedFilterBuilder#cache(boolean)`` method. See ?.

Caching
-------

By default, some filters are cached or not cached. You can have a fine
tuning control using ``cache(boolean)`` method when exists. For example:

.. code:: java

    FilterBuilder filter = andFilter(
            rangeFilter("postDate").from("2010-03-01").to("2010-04-01"),
            prefixFilter("name.second", "ba")
        )
        .cache(true);   

force caching filter
