[[query-dsl-filters]]
== Query DSL - Filters

elasticsearch provides a full Java query dsl in a similar manner to the
REST {ref}/query-dsl.html[Query DSL]. The factory for filter
builders is `FilterBuilders`.

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

See also how to build <<query-dsl-queries,Queries>>.

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

[source,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]]
=== And Filter

See {ref}/query-dsl-and-filter.html[And Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = andFilter(
    rangeFilter("postDate").from("2010-03-01").to("2010-04-01"),    <1>
    prefixFilter("name.second", "ba"));                             <1>
--------------------------------------------------
<1> filters

Note that you can cache the result using
`AndFilterBuilder#cache(boolean)` method. See <<query-dsl-filters-caching>>.


[[bool-filter]]
=== Bool Filter

See {ref}/query-dsl-bool-filter.html[Bool Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = boolFilter()
    .must(termFilter("tag", "wow"))                     <1>
    .mustNot(rangeFilter("age").from("10").to("20"))    <2>
    .should(termFilter("tag", "sometag"))               <3>
    .should(termFilter("tag", "sometagtag"));           <3>
--------------------------------------------------
<1> must filter
<2> must not filter
<3> should filter

Note that you can cache the result using
`BoolFilterBuilder#cache(boolean)` method. See <<query-dsl-filters-caching>>.


[[exists-filter]]
=== Exists Filter

See {ref}/query-dsl-exists-filter.html[Exists Filter].

[source,java]
--------------------------------------------------
FilterBuilder filter = existsFilter("user");    <1>
--------------------------------------------------
<1> field


[[ids-filter]]
=== Ids Filter

See {ref}/query-dsl-ids-filter.html[IDs Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = idsFilter("my_type", "type2")
    .addIds("1", "4", "100");

FilterBuilder filter = idsFilter() <1>
    .addIds("1", "4", "100");
--------------------------------------------------
<1> type is optional


[[limit-filter]]
=== Limit Filter

See {ref}/query-dsl-limit-filter.html[Limit Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = limitFilter(100);    <1>
--------------------------------------------------
<1> number of documents per shard


[[type-filter]]
=== Type Filter

See {ref}/query-dsl-type-filter.html[Type Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = typeFilter("my_type");   <1>
--------------------------------------------------
<1> type


[[geo-bbox-filter]]
=== Geo Bounding Box Filter

See {ref}/query-dsl-geo-bounding-box-filter.html[Geo
Bounding Box Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = geoBoundingBoxFilter("pin.location") <1>
    .topLeft(40.73, -74.1)                                  <2>
    .bottomRight(40.717, -73.99);                           <3>
--------------------------------------------------
<1> field
<2> bounding box top left point
<3> bounding box bottom right point

Note that you can cache the result using
`GeoBoundingBoxFilterBuilder#cache(boolean)` method. See
<<query-dsl-filters-caching>>.


[[geo-distance-filter]]
=== GeoDistance Filter

See {ref}/query-dsl-geo-distance-filter.html[Geo
Distance Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = geoDistanceFilter("pin.location")    <1>
    .point(40, -70)                                         <2>
    .distance(200, DistanceUnit.KILOMETERS)                 <3>
    .optimizeBbox("memory")                                 <4>
    .geoDistance(GeoDistance.ARC);                          <5>
--------------------------------------------------
<1> field
<2> center point
<3> distance from center point
<4> optimize bounding box: `memory`, `indexed` or `none`
<5> 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
<<query-dsl-filters-caching>>.


[[geo-distance-range-filter]]
=== Geo Distance Range Filter

See {ref}/query-dsl-geo-distance-range-filter.html[Geo
Distance Range Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = geoDistanceRangeFilter("pin.location")   <1>
    .point(40, -70)                                             <2>
    .from("200km")                                              <3>
    .to("400km")                                                <4>
    .includeLower(true)                                         <5>
    .includeUpper(false)                                        <6>
    .optimizeBbox("memory")                                     <7>
    .geoDistance(GeoDistance.ARC);                              <8>
--------------------------------------------------
<1> field
<2> center point
<3> starting distance from center point
<4> ending distance from center point
<5> include lower value means that `from` is `gt` when `false` or `gte` when `true`
<6> include upper value means that `to` is `lt` when `false` or `lte` when `true`
<7> optimize bounding box: `memory`, `indexed` or `none`
<8> 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
<<query-dsl-filters-caching>>.


[[geo-poly-filter]]
=== Geo Polygon Filter

See {ref}/query-dsl-geo-polygon-filter.html[Geo Polygon
Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = geoPolygonFilter("pin.location") <1>
    .addPoint(40, -70)                                  <2>
    .addPoint(30, -80)                                  <2>
    .addPoint(20, -90);                                 <2>
--------------------------------------------------
<1> field
<2> add your polygon of points a document should fall within

Note that you can cache the result using
`GeoPolygonFilterBuilder#cache(boolean)` method. See
<<query-dsl-filters-caching>>.


[[geo-shape-filter]]
=== Geo Shape Filter

See {ref}/query-dsl-geo-shape-filter.html[Geo Shape
Filter]

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:

[source,xml]
-----------------------------------------------
<dependency>
    <groupId>com.spatial4j</groupId>
    <artifactId>spatial4j</artifactId>
    <version>0.4.1</version>                        <1>
</dependency>

<dependency>
    <groupId>com.vividsolutions</groupId>
    <artifactId>jts</artifactId>
    <version>1.13</version>                         <2>
    <exclusions>
        <exclusion>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
        </exclusion>
    </exclusions>
</dependency>
-----------------------------------------------
<1> check for updates in http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.spatial4j%22%20AND%20a%3A%22spatial4j%22[Maven Central]
<2> check for updates in http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.vividsolutions%22%20AND%20a%3A%22jts%22[Maven Central]

[source,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;
--------------------------------------------------

[source,java]
--------------------------------------------------
// Shape within another
FilterBuilder filter = geoShapeFilter(
        "location",                                     <1>
        new RectangleImpl(0,10,0,10,SpatialContext.GEO) <2>
    )
    .relation(ShapeRelation.WITHIN);                    <3>
--------------------------------------------------
<1> field
<2> shape
<3> relation

[source,java]
--------------------------------------------------
// Intersect shapes
FilterBuilder filter = geoShapeFilter(
        "location",                                     <1>
        new PointImpl(0, 0, SpatialContext.GEO)         <2>
    )
    .relation(ShapeRelation.INTERSECTS);                <3>
--------------------------------------------------
<1> field
<2> shape
<3> relation

[source,java]
--------------------------------------------------
// Using pre-indexed shapes
FilterBuilder filter = geoShapeFilter(
        "location",                                     <1>
        "New Zealand",                                  <2>
        "countries")                                    <3>
    .relation(ShapeRelation.DISJOINT);                  <4>
--------------------------------------------------
<1> field
<2> indexed shape id
<3> index type of the indexed shapes
<4> relation


[[has-child-parent-filter]]
=== Has Child / Has Parent Filters

See:
 * {ref}/query-dsl-has-child-filter.html[Has Child Filter]
 * {ref}/query-dsl-has-parent-filter.html[Has Parent Filter]

[source,java]
--------------------------------------------------
// Has Child
QueryBuilder qb = hasChildFilter(
    "blog_tag",                     <1>
    termFilter("tag","something")   <2>
);
--------------------------------------------------
<1> child type to query against
<2> filter (could be also a query)

[source,java]
--------------------------------------------------
// Has Parent
QueryBuilder qb = hasParentFilter(
    "blog",                         <1>
    termFilter("tag","something")   <2>
);
--------------------------------------------------
<1> parent type to query against
<2> filter (could be also a query)


[[match-all-filter]]
=== Match All Filter

See {ref}/query-dsl-match-all-filter.html[Match All Filter]

[source,java]
--------------------------------------------------
FilterBuilder filter = matchAllFilter();
--------------------------------------------------


[[missing-filter]]
=== Missing Filter

See {ref}/query-dsl-missing-filter.html[Missing Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = missingFilter("user")    <1>
    .existence(true)                            <2>
    .nullValue(true);                           <3>
--------------------------------------------------
<1> field
<2> find missing field that doesn’t exist
<3> find missing field with an explicit `null` value

[[not-filter]]
=== Not Filter

See {ref}/query-dsl-not-filter.html[Not Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = notFilter(
    rangeFilter("price").from("1").to("2")  <1>
);
--------------------------------------------------
<1> filter


[[or-filter]]
=== Or Filter

See {ref}/query-dsl-or-filter.html[Or Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = orFilter(
        termFilter("name.second", "banon"), <1>
        termFilter("name.nick", "kimchy")   <1>
    );
--------------------------------------------------
<1> filters

Note that you can cache the result using
`OrFilterBuilder#cache(boolean)` method. See <<query-dsl-filters-caching>>.


[[prefix-filter]]
=== Prefix Filter

See {ref}/query-dsl-prefix-filter.html[Prefix Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = prefixFilter(
    "user", <1>
    "ki"    <2>
);
--------------------------------------------------
<1> field
<2> prefix

Note that you can cache the result using
`PrefixFilterBuilder#cache(boolean)` method. See <<query-dsl-filters-caching>>.


[[query-filter]]
=== Query Filter

See {ref}/query-dsl-query-filter.html[Query Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = queryFilter(
        queryString("this AND that OR thus")    <1>
    );
--------------------------------------------------
<1> query you want to wrap as a filter

Note that you can cache the result using
`QueryFilterBuilder#cache(boolean)` method. See <<query-dsl-filters-caching>>.


[[range-filter]]
=== Range Filter

See {ref}/query-dsl-range-filter.html[Range Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = rangeFilter("age")   <1>
    .from("10")                             <2>
    .to("20")                               <3>
    .includeLower(true)                     <4>
    .includeUpper(false);                   <5>
--------------------------------------------------
<1> field
<2> from
<3> to
<4> include lower value means that `from` is `gt` when `false` or `gte` when `true`
<5> include upper value means that `to` is `lt` when `false` or `lte` when `true`

[source,java]
--------------------------------------------------
// A simplified form using gte, gt, lt or lte
FilterBuilder filter = rangeFilter("age")   <1>
    .gte("10")                              <2>
    .lt("20");                              <3>
--------------------------------------------------
<1> field
<2> set `from` to 10 and `includeLower` to true
<3> set `to` to 20 and `includeUpper` to false

Note that you can ask not to cache the result using
`RangeFilterBuilder#cache(boolean)` method. See <<query-dsl-filters-caching>>.


[[script-filter]]
=== Script Filter

See {ref}/query-dsl-script-filter.html[Script Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = scriptFilter(
        "doc['age'].value > param1" <1>
    ).addParam("param1", 10);       <2>
--------------------------------------------------
<1> script to execute
<2> parameters

Note that you can cache the result using
`ScriptFilterBuilder#cache(boolean)` method. See <<query-dsl-filters-caching>>.


[[term-filter]]
=== Term Filter

See {ref}/query-dsl-term-filter.html[Term Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = termFilter(
    "user",     <1>
    "kimchy"    <2>
);
--------------------------------------------------
<1> field
<2> value

Note that you can ask not to cache the result using
`TermFilterBuilder#cache(boolean)` method. See <<query-dsl-filters-caching>>.


[[terms-filter]]
=== Terms Filter

See {ref}/query-dsl-terms-filter.html[Terms Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = termsFilter(
        "user",             <1>
        "kimchy",           <2>
        "elasticsearch"     <2>
    )
    .execution("plain");    <3>
--------------------------------------------------
<1> field
<2> terms
<3> 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 <<query-dsl-filters-caching>>.


[[nested-filter]]
=== Nested Filter

See {ref}/query-dsl-nested-filter.html[Nested Filter]


[source,java]
--------------------------------------------------
FilterBuilder filter = nestedFilter("obj1",                     <1>
    boolFilter()                                                <2>
        .must(termFilter("obj1.name", "blue"))
        .must(rangeFilter("obj1.count").gt(5))
    );
--------------------------------------------------
<1> path to nested document
<2> filter

Note that you can ask not to cache the result using
`NestedFilterBuilder#cache(boolean)` method. See <<query-dsl-filters-caching>>.

[[query-dsl-filters-caching]]
=== 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:

[source,java]
--------------------------------------------------
FilterBuilder filter = andFilter(
        rangeFilter("postDate").from("2010-03-01").to("2010-04-01"),
        prefixFilter("name.second", "ba")
    )
    .cache(true);   <1>
--------------------------------------------------
<1> force caching filter
