<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<link rel='stylesheet' href='static/styles.css' type='text/css'>
<script type='text/javascript' src='static/script.js'></script>
</head>
<body>
<div class="pod">    


<ul id="index">
  <li><a href="#NAME">NAME</a></li>
  <li><a href="#VERSION">VERSION</a></li>
  <li><a href="#DESCRIPTION">DESCRIPTION</a></li>
  <li><a href="#SYNOPSIS">SYNOPSIS</a></li>
  <li><a href="#METHODS">METHODS</a>
    <ul>
      <li><a href="#new-">new()</a></li>
      <li><a href="#query-">query()</a></li>
      <li><a href="#filter-">filter()</a></li>
    </ul>
  </li>
  <li><a href="#INTRODUCTION">INTRODUCTION</a>
    <ul>
      <li><a href="#QUERY-FILTER-CONTEXT">QUERY / FILTER CONTEXT</a>
        <ul>
          <li><a href="#filter--not_filter">-filter | -not_filter</a></li>
          <li><a href="#query--not_query">-query | -not_query</a></li>
        </ul>
      </li>
      <li><a href="#KEY-VALUE-PAIRS">KEY-VALUE PAIRS</a></li>
      <li><a href="#AND-OR-LOGIC">AND|OR LOGIC</a>
        <ul>
          <li><a href="#and--or--not">-and | -or | -not</a></li>
        </ul>
      </li>
      <li><a href="#FIELD-OPERATORS">FIELD OPERATORS</a></li>
      <li><a href="#UNARY-OPERATORS">UNARY OPERATORS</a></li>
    </ul>
  </li>
  <li><a href="#MATCH-ALL">MATCH ALL</a>
    <ul>
      <li><a href="#all">-all</a></li>
    </ul>
  </li>
  <li><a href="#EQUALITY">EQUALITY</a>
    <ul>
      <li><a href="#EQUALITY-QUERIES-">EQUALITY (QUERIES)</a>
        <ul>
          <li><a href="#match--not_match">= | -match | != | &lt;&gt; | -not_match</a></li>
          <li><a href="#phrase--not_phrase">== | -phrase | -not_phrase</a></li>
          <li><a href="#Multi-field--match--not_match">Multi-field -match | -not_match</a></li>
          <li><a href="#term--terms--not_term--not_terms">-term | -terms | -not_term | -not_terms</a></li>
        </ul>
      </li>
      <li><a href="#EQUALITY-FILTERS-">EQUALITY (FILTERS)</a>
        <ul>
          <li><a href="#term--terms--not_term--not_terms1">= | -term | -terms | &lt;&gt; | != | -not_term | -not_terms</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><a href="#RANGES">RANGES</a>
    <ul>
      <li><a href="#lt-gt-lte-gte--range--not_range">lt | gt | lte | gte | &lt; | &lt;= | &gt;= | &gt; | -range | -not_range</a></li>
    </ul>
  </li>
  <li><a href="#MISSING-OR-NULL-VALUES">MISSING OR NULL VALUES</a>
    <ul>
      <li><a href="#missing--exists">-missing | -exists</a></li>
    </ul>
  </li>
  <li><a href="#FULL-TEXT-SEARCH">FULL TEXT SEARCH</a>
    <ul>
      <li><a href="#qs--query_string--not_qs--not_query_string">-qs | -query_string | -not_qs | -not_query_string</a></li>
      <li><a href="#mlt--not_mlt">-mlt | -not_mlt</a></li>
      <li><a href="#flt--not_flt">-flt | -not_flt</a></li>
    </ul>
  </li>
  <li><a href="#PREFIX">PREFIX</a>
    <ul>
      <li><a href="#PREFIX-QUERIES-">PREFIX (QUERIES)</a>
        <ul>
          <li><a href="#phrase_prefix--not_phrase_prefix">^ | -phrase_prefix | -not_phrase_prefix</a></li>
          <li><a href="#prefix--not_prefix">-prefix | -not_prefix</a></li>
        </ul>
      </li>
      <li><a href="#PREFIX-FILTERS-">PREFIX (FILTERS)</a>
        <ul>
          <li><a href="#prefix--not_prefix1">^ | -prefix | -not_prefix</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><a href="#WILDCARD-AND-FUZZY-QUERIES">WILDCARD AND FUZZY QUERIES</a>
    <ul>
      <li><a href="#wildcard--not_wildcard">* | -wildcard | -not_wildcard</a></li>
      <li><a href="#fuzzy--not_fuzzy">-fuzzy | -not_fuzzy</a></li>
    </ul>
  </li>
  <li><a href="#COMBINING-QUERIES">COMBINING QUERIES</a>
    <ul>
      <li><a href="#dis_max--dismax">-dis_max | -dismax</a></li>
      <li><a href="#bool">-bool</a></li>
      <li><a href="#boosting">-boosting</a></li>
      <li><a href="#custom_boost">-custom_boost</a></li>
    </ul>
  </li>
  <li><a href="#NESTED-QUERIES-FILTERS">NESTED QUERIES/FILTERS</a>
    <ul>
      <li><a href="#nested-QUERY-">-nested (QUERY)</a></li>
      <li><a href="#nested-FILTER-">-nested (FILTER)</a></li>
    </ul>
  </li>
  <li><a href="#SCRIPTING">SCRIPTING</a>
    <ul>
      <li><a href="#custom_score">-custom_score</a></li>
      <li><a href="#custom_filters_score">-custom_filters_score</a></li>
      <li><a href="#script">-script</a></li>
    </ul>
  </li>
  <li><a href="#PARENT-CHILD">PARENT/CHILD</a>
    <ul>
      <li><a href="#has_parent--not_has_parent">-has_parent | -not_has_parent</a></li>
      <li><a href="#has_child--not_has_child">-has_child | -not_has_child</a></li>
      <li><a href="#top_children">-top_children</a></li>
    </ul>
  </li>
  <li><a href="#GEO-FILTERS">GEO FILTERS</a>
    <ul>
      <li><a href="#geo_distance--not_geo_distance">-geo_distance | -not_geo_distance</a></li>
      <li><a href="#geo_distance_range--not_geo_distance_range">-geo_distance_range | -not_geo_distance_range</a></li>
      <li><a href="#geo_bounding_box--geo_bbox--not_geo_bounding_box--not_geo_bbox">-geo_bounding_box | -geo_bbox | -not_geo_bounding_box | -not_geo_bbox</a></li>
      <li><a href="#geo_polygon--not_geo_polygon">-geo_polygon | -not_geo_polygon</a></li>
    </ul>
  </li>
  <li><a href="#INDEX-TYPE-ID">INDEX/TYPE/ID</a>
    <ul>
      <li><a href="#indices">-indices</a></li>
      <li><a href="#ids">-ids</a></li>
      <li><a href="#type">-type</a></li>
    </ul>
  </li>
  <li><a href="#LIMIT">LIMIT</a></li>
  <li><a href="#NAMED-FILTERS">NAMED FILTERS</a>
    <ul>
      <li><a href="#name--not_name">-name | -not_name</a></li>
    </ul>
  </li>
  <li><a href="#CACHING-FILTERS">CACHING FILTERS</a>
    <ul>
      <li><a href="#cache--nocache">-cache | -nocache</a></li>
      <li><a href="#cache_key">-cache_key</a></li>
    </ul>
  </li>
  <li><a href="#RAW-ELASTICSEARCH-QUERY-DSL">RAW ELASTICSEARCH QUERY DSL</a></li>
  <li><a href="#ELASTICSEARCH-CONCEPTS">ELASTICSEARCH CONCEPTS</a>
    <ul>
      <li><a href="#FILTERS-VS-QUERIES">FILTERS VS QUERIES</a></li>
      <li><a href="#TERMS-VS-TEXT">TERMS VS TEXT</a></li>
      <li><a href="#match-QUERIES"><code>match</code> QUERIES</a></li>
    </ul>
  </li>
  <li><a href="#AUTHOR">AUTHOR</a></li>
  <li><a href="#BUGS">BUGS</a></li>
  <li><a href="#TODO">TODO</a></li>
  <li><a href="#SUPPORT">SUPPORT</a></li>
  <li><a href="#ACKNOWLEDGEMENTS">ACKNOWLEDGEMENTS</a></li>
  <li><a href="#LICENSE-AND-COPYRIGHT">LICENSE AND COPYRIGHT</a></li>
</ul>

<h1 id="NAME">NAME</h1>

<p>ElasticSearch::SearchBuilder - A Perlish compact query language for ElasticSearch</p>

<h1 id="VERSION">VERSION</h1>

<p>Version 0.14</p>

<p>Compatible with ElasticSearch version 0.19.7</p>

<h1 id="DESCRIPTION">DESCRIPTION</h1>

<p>The Query DSL for ElasticSearch (see <a href="http://www.elasticsearch.org/guide/reference/query-dsl">Query DSL</a>), which is used to write queries and filters, is simple but verbose, which can make it difficult to write and understand large queries.</p>

<p><a href="./ElasticSearch::SearchBuilder">ElasticSearch::SearchBuilder</a> is an <a href="./SQL::Abstract">SQL::Abstract</a>-like query language which exposes the full power of the query DSL, but in a more compact, Perlish way.</p>

<p><b>This module is considered stable.</b> If you have suggestions for improvements to the API or the documenation, please contact me.</p>

<h1 id="SYNOPSIS">SYNOPSIS</h1>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    my $sb = ElasticSearch::SearchBuilder-&gt;new();
    my $query = $sb-&gt;query({
        body    =&gt; &#39;interesting keywords&#39;,
        -filter =&gt; {
            status  =&gt; &#39;active&#39;,
            tags    =&gt; [&#39;perl&#39;,&#39;python&#39;,&#39;ruby&#39;],
            created =&gt; {
                &#39;&gt;=&#39; =&gt; &#39;2010-01-01&#39;,
                &#39;&lt;&#39;  =&gt; &#39;2011-01-01&#39;
            },
        }
    })</pre>

<p><b>NOTE</b>: <code>ElasticSearch::SearchBuilder</code> is fully integrated with the <a href="./ElasticSearch">ElasticSearch</a> API. Wherever you can specify <code>query</code>, <code>filter</code> or <code>facet_filter</code> in <a href="./ElasticSearch">ElasticSearch</a>, you can automatically use SearchBuilder by specifying <code>queryb</code>, <code>filterb</code>, <code>facet_filterb</code> instead.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    $es-&gt;search( queryb  =&gt; { body =&gt; &#39;interesting keywords&#39; } )</pre>

<h1 id="METHODS">METHODS</h1>

<h2 id="new-">new()</h2>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    my $sb = ElastiSearch::SearchBuilder-&gt;new()</pre>

<p>Creates a new instance of the SearchBuilder - takes no parameters.</p>

<h2 id="query-">query()</h2>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    my $es_query = $sb-&gt;query($compact_query)</pre>

<p>Returns a query in the ElasticSearch query DSL.</p>

<p><code>$compact_query</code> can be a scalar, a hash ref or an array ref.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    $sb-&gt;query(&#39;foo&#39;)
    # { &quot;query&quot; : { &quot;match&quot; : { &quot;_all&quot; : &quot;foo&quot; }}}

    $sb-&gt;query({ ... }) or $sb-&gt;query([ ... ])
    # { &quot;query&quot; : { ... }}</pre>

<h2 id="filter-">filter()</h2>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    my $es_filter = $sb-&gt;filter($compact_filter)</pre>

<p>Returns a filter in the ElasticSearch query DSL.</p>

<p><code>$compact_filter</code> can be a scalar, a hash ref or an array ref.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    $sb-&gt;filter(&#39;foo&#39;)
    # { &quot;filter&quot; : { &quot;term&quot; : { &quot;_all&quot; : &quot;foo&quot; }}}

    $sb-&gt;filter({ ... }) or $sb-&gt;filter([ ... ])
    # { &quot;filter&quot; : { ... }}</pre>

<h1 id="INTRODUCTION">INTRODUCTION</h1>

<p><b>IMPORTANT</b>: If you are not familiar with ElasticSearch then you should read <a href="#ELASTICSEARCH-CONCEPTS">&quot;ELASTICSEARCH CONCEPTS&quot;</a> before continuing.</p>

<p>This module was inspired by <a href="./SQL::Abstract">SQL::Abstract</a> but they are not compatible with each other.</p>

<p>The easiest way to explain how the syntax works is to give examples:</p>

<h2 id="QUERY-FILTER-CONTEXT">QUERY / FILTER CONTEXT</h2>

<p>There are two contexts:</p>

<ul>

<li><p><code>filter</code> context</p>

<p>Filter are fast and cacheable. They should be used to include/exclude docs, based on simple term values. For instance, exclude all docs that have neither tag <code>perl</code> nor <code>python</code>.</p>

<p>Typically, most of your clauses should be filters, which reduce the number of docs that need to be passed to the query.</p>

</li>
<li><p><code>query</code> context</p>

<p>Queries are smarter than filters, but more expensive, as they have to calculate search relevance (ie <code>_score</code>).</p>

<p>They should be used where:</p>

<ul>

<li><p>relevance is important, eg: in a search for tags <code>perl</code> or <code>python</code>, a doc that has BOTH tags is more relevant than a doc that has only one</p>

</li>
<li><p>where search terms need to be analyzed as full text, eg: find me all docs where the <code>content</code> field includes the words &quot;Perl is GREAT&quot;, no matter how those words are capitalized.</p>

</li>
</ul>

</li>
</ul>

<p>The available operators (and the query/filter clauses that are generated) differ according to which context you are in.</p>

<p>The initial context depends upon which method you use: <a href="#query-">&quot;query()&quot;</a> puts you into <code>query</code> context, and <a href="#filter-">&quot;filter()&quot;</a> into <code>filter</code> context.</p>

<p>However, you can switch from one context to another as follows:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    $sb-&gt;query({

        # query context
        foo     =&gt; 1,
        bar     =&gt; 2,

        -filter =&gt; {
            # filter context
            foo     =&gt; 1,
            bar     =&gt; 2,

            -query  =&gt; {
                # query context
                foo =&gt; 1
            }
        }
    })</pre>

<h3 id="filter--not_filter">-filter | -not_filter</h3>

<p>Switch from query context to filter context:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # query field content for &#39;brown cow&#39;, and filter documents
    # where status is &#39;active&#39; and tags contains the term &#39;perl&#39;
    {
        content =&gt; &#39;brown cow&#39;,
        -filter =&gt; {
            status =&gt; &#39;active&#39;,
            tags   =&gt; &#39;perl&#39;
        }
    }


    # no query, just a filter:
    { -filter =&gt; { status =&gt; &#39;active&#39; }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/filtered-query.html">Filtered Query</a> and <a href="http://www.elasticsearch.org/guide/reference/query-dsl/constant-score-query.html">Constant Score Query</a></p>

<h3 id="query--not_query">-query | -not_query</h3>

<p>Use a query as a filter:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # query field content for &#39;brown cow&#39;, and filter documents
    # where status is &#39;active&#39;, tags contains the term &#39;perl&#39;
    # and a match query on field title contains &#39;important&#39;
    {
        content =&gt; &#39;brown cow&#39;,
        -filter =&gt; {
            status =&gt; &#39;active&#39;,
            tags   =&gt; &#39;perl&#39;,
            -query =&gt; {
                title =&gt; &#39;important&#39;
            }
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/query-filter.html">Query Filter</a></p>

<h2 id="KEY-VALUE-PAIRS">KEY-VALUE PAIRS</h2>

<p>Key-value pairs are equivalent to the <code>=</code> operator, discussed below. They are converted to <code>match</code> queries or <code>term</code> filters:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field &#39;foo&#39; contains term &#39;bar&#39;
    # equiv: { foo =&gt; { &#39;=&#39; =&gt; &#39;bar&#39; }}
    { foo =&gt; &#39;bar&#39; }



    # Field &#39;foo&#39; contains &#39;bar&#39; or &#39;baz&#39;
    # equiv: { foo =&gt; { &#39;=&#39; =&gt; [&#39;bar&#39;,&#39;baz&#39;] }}
    { foo =&gt; [&#39;bar&#39;,&#39;baz&#39;]}


    # Field &#39;foo&#39; contains terms &#39;bar&#39; AND &#39;baz&#39;
    # equiv: { foo =&gt; { &#39;-and&#39; =&gt; [ {&#39;=&#39; =&gt; &#39;bar&#39;}, {&#39;=&#39; =&gt; &#39;baz&#39;}] }}
    { foo =&gt; [&#39;-and&#39;,&#39;bar&#39;,&#39;baz&#39;]}


    ### FILTER ONLY ###

    # Field &#39;foo&#39; is missing ie has no value
    # equiv: { -missing =&gt; &#39;foo&#39; }
    { foo =&gt; undef }</pre>

<h2 id="AND-OR-LOGIC">AND|OR LOGIC</h2>

<p>Arrays are OR&#39;ed, hashes are AND&#39;ed:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # tags = &#39;perl&#39; AND status = &#39;active:
    {
        tags   =&gt; &#39;perl&#39;,
        status =&gt; &#39;active&#39;
    }

    # tags = &#39;perl&#39; OR status = &#39;active:
    [
        tags   =&gt; &#39;perl&#39;,
        status =&gt; &#39;active&#39;
    ]

    # tags = &#39;perl&#39; or tags = &#39;python&#39;:
    { tags =&gt; [ &#39;perl&#39;,&#39;python&#39; ]}
    { tags =&gt; { &#39;=&#39; =&gt; [ &#39;perl&#39;,&#39;python&#39; ] }}

    # tags begins with prefix &#39;p&#39; or &#39;r&#39;
    { tags =&gt; { &#39;^&#39; =&gt; [ &#39;p&#39;,&#39;r&#39; ] }}</pre>

<p>The logic in an array can changed from <code>OR</code> to <code>AND</code> by making the first element of the array ref <code>-and</code>:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # tags has term &#39;perl&#39; AND &#39;python&#39;

    { tags =&gt; [&#39;-and&#39;,&#39;perl&#39;,&#39;python&#39;]}

    {
        tags =&gt; [
            -and =&gt; { &#39;=&#39; =&gt; &#39;perl&#39;},
                    { &#39;=&#39; =&gt; &#39;python&#39;}
        ]
    }</pre>

<p>However, the first element in an array ref which is used as the value for a field operator (see <a href="#FIELD-OPERATORS">&quot;FIELD OPERATORS&quot;</a>) is not special:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # WRONG
    { tags =&gt; { &#39;=&#39; =&gt; [ &#39;-and&#39;,&#39;perl&#39;,&#39;python&#39; ] }}

    # RIGHT
    { tags =&gt; [&#39;-and&#39; =&gt; [ {&#39;=&#39; =&gt; &#39;perl&#39;}, {&#39;=&#39; =&gt; &#39;python&#39;} ] ]}</pre>

<p>...otherwise you would never be able to search for the term <code>-and</code>. So if you might possibly have the terms <code>-and</code> or <code>-or</code> in your data, use:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    { foo =&gt; {&#39;=&#39; =&gt; [....] }}</pre>

<p>instead of:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    { foo =&gt; [....]}</pre>

<h3 id="and--or--not">-and | -or | -not</h3>

<p>These unary operators allow you apply <code>and</code>, <code>or</code> and <code>not</code> logic to nested queries or filters.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo has both terms &#39;bar&#39; and &#39;baz&#39;
    { -and =&gt; [
            foo =&gt; &#39;bar&#39;,
            foo =&gt; &#39;baz&#39;
    ]}

    # Field &#39;name&#39; contains &#39;john smith&#39;, or the name field is missing
    # and the &#39;desc&#39; field contains &#39;john smith&#39;

    { -or =&gt; [
        { name =&gt; &#39;John Smith&#39; },
        {
            desc     =&gt; &#39;John Smith&#39;
            -filter  =&gt; { -missing =&gt; &#39;name&#39; },
        }
    ]}</pre>

<p>The <code>-and</code>, <code>-or</code> and <code>-not</code> constructs emit <code>bool</code> queries when in query context, and <code>and</code>, <code>or</code> and <code>not</code> clauses when in filter context.</p>

<p>See also: <a href="#NAMED-FILTERS">&quot;NAMED FILTERS&quot;</a>, <a href="http://www.elasticsearch.org/guide/reference/query-dsl/bool-query.html">Bool Query</a>, <a href="http://www.elasticsearch.org/guide/reference/query-dsl/and-filter.html">And Filter</a>, <a href="http://www.elasticsearch.org/guide/reference/query-dsl/or-filter.html">Or Filter</a> and <a href="http://www.elasticsearch.org/guide/reference/query-dsl/not-filter.html">Not Filter</a></p>

<h2 id="FIELD-OPERATORS">FIELD OPERATORS</h2>

<p>Most operators (eg <code>=</code>, <code>gt</code>, <code>geo_distance</code> etc) are applied to a particular field. These are known as <code>Field Operators</code>. For example:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo contains the term &#39;bar&#39;
    { foo =&gt; &#39;bar&#39; }
    { foo =&gt; {&#39;=&#39; =&gt; &#39;bar&#39; }}

    # Field created is between Jan 1 and Dec 31 2010
    { created =&gt; {
        &#39;&gt;=&#39;  =&gt; &#39;2010-01-01&#39;,
        &#39;&lt;&#39;   =&gt; &#39;2011-01-01&#39;
    }}

    # Field foo contains terms which begin with prefix &#39;a&#39; or &#39;b&#39; or &#39;c&#39;
    { foo =&gt; { &#39;^&#39; =&gt; [&#39;a&#39;,&#39;b&#39;,&#39;c&#39; ]}}</pre>

<p>Some field operators are available as symbols (eg <code>=</code>, <code>*</code>, <code>^</code>, <code>gt</code>) and others as words (eg <code>geo_distance</code> or <code>-geo_distance</code> - the dash is optional).</p>

<p>Multiple field operators can be applied to a single field. Use <code>{}</code> to imply <code>this AND that</code>:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo has any value from 100 to 200
    { foo =&gt; { gte =&gt; 100, lte =&gt; 200 }}

    # Field foo begins with &#39;p&#39; but is not python
    { foo =&gt; {
        &#39;^&#39;  =&gt; &#39;p&#39;,
        &#39;!=&#39; =&gt; &#39;python&#39;
    }}</pre>

<p>Or <code>[]</code> to imply <code>this OR that</code></p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # foo is 5 or foo greater than 10
    { foo =&gt; [
        { &#39;=&#39;  =&gt; 5  },
        { &#39;gt&#39; =&gt; 10 }
    ]}</pre>

<p>All word operators may be negated by adding <code>not_</code> to the beginning, eg:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo does NOT contain a term beginning with &#39;bar&#39; or &#39;baz&#39;
    { foo =&gt; { not_prefix =&gt; [&#39;bar&#39;,&#39;baz&#39;] }}</pre>

<h2 id="UNARY-OPERATORS">UNARY OPERATORS</h2>

<p>There are other operators which don&#39;t fit this <code>{ field =&gt; { op =&gt; value }}</code> model.</p>

<p>For instance:</p>

<ul>

<li><p>An operator might apply to multiple fields:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Search fields &#39;title&#39; and &#39;content&#39; for text &#39;brown cow&#39;
    {
        -match =&gt; {
            query   =&gt; &#39;brown cow&#39;,
            fields  =&gt; [&#39;title&#39;,&#39;content&#39;]
        }
    }</pre>

</li>
<li><p>The field might BE the value:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Find documents where the field &#39;foo&#39; is blank or undefined
    { -missing =&gt; &#39;foo&#39; }

    # Find documents where the field &#39;foo&#39; exists and has a value
    { -exists =&gt; &#39;foo&#39; }</pre>

</li>
<li><p>For combining other queries or filters:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo has terms &#39;bar&#39; and &#39;baz&#39; but not &#39;balloo&#39;
    {
        -and =&gt; [
            foo =&gt; &#39;bar&#39;,
            foo =&gt; &#39;baz&#39;,
            -not =&gt; { foo =&gt; &#39;balloo&#39; }
        ]
    }</pre>

</li>
<li><p>Other:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Script query
    { -script =&gt; &quot;doc[&#39;num1&#39;].value &gt; 1&quot; }</pre>

</li>
</ul>

<p>These operators are called <code>unary operators</code> and ALWAYS begin with a dash <code>-</code> to distinguish them from field names.</p>

<p>Unary operators may also be prefixed with <code>not_</code> to negate their meaning.</p>

<h1 id="MATCH-ALL">MATCH ALL</h1>

<h2 id="all">-all</h2>

<p>The <code>-all</code> operator matches all documents:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # match all
    { -all =&gt; 1  }
    { -all =&gt; 0  }
    { -all =&gt; {} }</pre>

<p>In query context, the <code>match_all</code> query usually scores all docs as 1 (ie having the same relevance). By specifying a <code>norms_field</code>, the relevance can be read from that field (at the cost of a slower execution time):</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Query context only
    { -all =&gt;{
        boost       =&gt; 1,
        norms_field =&gt; &#39;doc_boost&#39;
    }}</pre>

<h1 id="EQUALITY">EQUALITY</h1>

<p>These operators answer the question: &quot;Does this field contain this term?&quot;</p>

<p>Filter equality operators work only with exact terms, while query equality operators (the <code>match</code> family of queries) will &quot;do the right thing&quot;, ie work with terms for <code>not_analyzed</code> fields and with analyzed text for <code>analyzed</code> fields.</p>

<h2 id="EQUALITY-QUERIES-">EQUALITY (QUERIES)</h2>

<h3 id="match--not_match">= | -match | != | &lt;&gt; | -not_match</h3>

<p>These operators all generate <code>match</code> queries:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Analyzed field &#39;title&#39; contains the terms &#39;Perl is GREAT&#39;
    # (which is analyzed to the terms &#39;perl&#39;,&#39;great&#39;)
    { title =&gt; &#39;Perl is GREAT&#39; }
    { title =&gt; { &#39;=&#39;  =&gt; &#39;Perl is GREAT&#39; }}
    { title =&gt; { match =&gt; &#39;Perl is GREAT&#39; }}

    # Not_analyzed field &#39;status&#39; contains the EXACT term &#39;ACTIVE&#39;
    { status =&gt; &#39;ACTIVE&#39; }
    { status =&gt; { &#39;=&#39;  =&gt; &#39;ACTIVE&#39; }}
    { status =&gt; { match =&gt; &#39;ACTIVE&#39; }}

    # Same as above but with extra parameters:
    { title =&gt; {
        match =&gt; {
            query                =&gt; &#39;Perl is GREAT&#39;,
            boost                =&gt; 2.0,
            operator             =&gt; &#39;and&#39;,
            analyzer             =&gt; &#39;default&#39;,
            fuzziness            =&gt; 0.5,
            fuzzy_rewrite        =&gt; &#39;constant_score_default&#39;,
            lenient              =&gt; 1,
            max_expansions       =&gt; 100,
            minimum_should_match =&gt; 2,
            prefix_length        =&gt; 2,
        }
    }}</pre>

<p>Operators <code>&lt;&gt;</code>, <code>!=</code> and <code>not_match</code> are synonyms for each other and just wrap the operator in a <code>not</code> clause.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/match-query.html">Match Query</a></p>

<h3 id="phrase--not_phrase">== | -phrase | -not_phrase</h3>

<p>These operators look for a complete phrase.</p>

<p>For instance, given the text</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    The quick brown fox jumped over the lazy dog.

    # matches
    { content =&gt; { &#39;==&#39; =&gt; &#39;Quick Brown&#39; }}

    # doesn&#39;t match
    { content =&gt; { &#39;==&#39; =&gt; &#39;Brown Quick&#39; }}
    { content =&gt; { &#39;==&#39; =&gt; &#39;Quick Fox&#39;   }}</pre>

<p>The <code>slop</code> parameter can be used to allow the phrase to match words in the same order, but further apart:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # with other parameters
    { content =&gt; {
        phrase =&gt; {
            query    =&gt; &#39;Quick Fox&#39;,
            slop     =&gt; 3,
            analyzer =&gt; &#39;default&#39;
            boost    =&gt; 1,
            lenient  =&gt; 1,
    }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/match-query.html">Match Query</a></p>

<h3 id="Multi-field--match--not_match">Multi-field -match | -not_match</h3>

<p>To run a <code>match</code> | <code>=</code>, <code>phrase</code> or <code>phrase_prefix</code> query against multiple fields, you can use the <code>-match</code> unary operator:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -match =&gt; {
            query                =&gt; &quot;Quick Fox&quot;,
            type                 =&gt; &#39;boolean&#39;,
            fields               =&gt; [&#39;content&#39;,&#39;title&#39;],

            use_dis_max          =&gt; 1,
            tie_breaker          =&gt; 0.7,

            boost                =&gt; 2.0,
            operator             =&gt; &#39;and&#39;,
            analyzer             =&gt; &#39;default&#39;,
            fuzziness            =&gt; 0.5,
            fuzzy_rewrite        =&gt; &#39;constant_score_default&#39;,
            lenient              =&gt; 1,
            max_expansions       =&gt; 100,
            minimum_should_match =&gt; 2,
            prefix_length        =&gt; 2,
        }
    }</pre>

<p>The <code>type</code> parameter can be <code>boolean</code> (equivalent of <code>match</code> | <code>=</code>) which is the default, <code>phrase</code> or <code>phrase_prefix</code>.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query.html">Multi-match Query</a>.</p>

<h3 id="term--terms--not_term--not_terms">-term | -terms | -not_term | -not_terms</h3>

<p>The <code>term</code>/<code>terms</code> operators are provided for completeness. You should almost always use the <code>match</code>/<code>=</code> operator instead.</p>

<p>There are only two use cases:</p>

<ul>

<li><p>To find the exact (ie not analyzed) term &#39;foo&#39; in an analyzed field:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    { title =&gt; { term =&gt; &#39;foo&#39; }}</pre>

</li>
<li><p>To match a list of possible terms, where more than 1 value must match:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # match 2 or more of these tags
    { tags =&gt; {
        terms =&gt; {
            value         =&gt; [&#39;perl&#39;,&#39;python&#39;,&#39;php&#39;],
            minimum_match =&gt; 2,
            boost         =&gt; 1,
        }
    }}</pre>

<p>The above can also be achieved with the <a href="#bool">&quot;-bool&quot;</a> operator.</p>

</li>
</ul>

<p><code>term</code> and <code>terms</code> are synonyms, as are <code>not_term</code> and <code>not_terms</code>.</p>

<h2 id="EQUALITY-FILTERS-">EQUALITY (FILTERS)</h2>

<h3 id="term--terms--not_term--not_terms1">= | -term | -terms | &lt;&gt; | != | -not_term | -not_terms</h3>

<p>These operators result in <code>term</code> or <code>terms</code> filters, which look for fields which contain exactly the terms specified:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo has the term &#39;bar&#39;:
    { foo =&gt; &#39;bar&#39; }
    { foo =&gt; { &#39;=&#39;    =&gt; &#39;bar&#39; }}
    { foo =&gt; { &#39;term&#39; =&gt; &#39;bar&#39; }}

    # Field foo has the term &#39;bar&#39; or &#39;baz&#39;
    { foo =&gt; [&#39;bar&#39;,&#39;baz&#39;] }
    { foo =&gt; { &#39;=&#39;     =&gt; [&#39;bar&#39;,&#39;baz&#39;] }}
    { foo =&gt; { &#39;term&#39;  =&gt; [&#39;bar&#39;,&#39;baz&#39;] }}</pre>

<p><code>&lt;&gt;</code> and <code>!=</code> are synonyms:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo does not contain the term &#39;bar&#39;:
    { foo =&gt; { &#39;!=&#39; =&gt; &#39;bar&#39; }}
    { foo =&gt; { &#39;&lt;&gt;&#39; =&gt; &#39;bar&#39; }}

    # Field foo contains neither &#39;bar&#39; nor &#39;baz&#39;
    { foo =&gt; { &#39;!=&#39; =&gt; [&#39;bar&#39;,&#39;baz&#39;] }}
    { foo =&gt; { &#39;&lt;&gt;&#39; =&gt; [&#39;bar&#39;,&#39;baz&#39;] }}</pre>

<p>The <code>terms</code> filter can take an <code>execution</code> parameter which affects how the filter of multiple terms is executed and cached.</p>

<p>For instance:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    { foo =&gt; {
        -terms =&gt; {
            value       =&gt; [&#39;foo&#39;,&#39;bar&#39;],
            execution   =&gt; &#39;bool&#39;
        }
    }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/term-filter.html">Term Filter</a> and <a href="http://www.elasticsearch.org/guide/reference/query-dsl/terms-filter.html">Terms Filter</a></p>

<h1 id="RANGES">RANGES</h1>

<h2 id="lt-gt-lte-gte--range--not_range">lt | gt | lte | gte | &lt; | &lt;= | &gt;= | &gt; | -range | -not_range</h2>

<p>These operators imply a range query or filter, which can be numeric or alphabetical.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo contains terms between &#39;alpha&#39; and &#39;beta&#39;
    { foo =&gt; {
        &#39;gte&#39;   =&gt; &#39;alpha&#39;,
        &#39;lte&#39;   =&gt; &#39;beta&#39;
    }}

    # Field foo contains numbers between 10 and 20
    { foo =&gt; {
        &#39;gte&#39;   =&gt; &#39;10&#39;,
        &#39;lte&#39;   =&gt; &#39;20&#39;
    }}

    # boost a range  *** query only ***
    { foo =&gt; {
        range =&gt; {
            gt      =&gt; 5,
            gte     =&gt; 5,
            lt      =&gt; 10,
            lte     =&gt; 10,
            boost   =&gt; 2.0
        }
    }}</pre>

<p>For queries, <code>&lt;</code> is a synonym for <code>lt</code>, <code>&gt;</code> for <code>gt</code> etc.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/range-query.html">Range Query</a></p>

<p><b>Note</b>: for filter clauses, the <code>gt</code>,<code>gte</code>,<code>lt</code> and <code>lte</code> operators imply a <code>range</code> filter, while the <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code> and <code>&gt;=</code> operators imply a <code>numeric_range</code> filter.</p>

<p><b>This does not mean that you should use the <code>numeric_range</code> version for any field which contains numbers!</b></p>

<p>The <code>numeric_range</code> filter should be used for numbers/datetimes which have many distinct values, eg <code>ID</code> or <code>last_modified</code>. If you have a numeric field with few distinct values, eg <code>number_of_fingers</code> then it is better to use a <code>range</code> filter.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/range-filter.html">Range Filter</a> and <a href="http://www.elasticsearch.org/guide/reference/query-dsl/numeric-range-filter.html">Numeric Range Filter</a>.</p>

<h1 id="MISSING-OR-NULL-VALUES">MISSING OR NULL VALUES</h1>

<p>*** Filter context only ***</p>

<h2 id="missing--exists">-missing | -exists</h2>

<p>You can use a <code>missing</code> or <code>exists</code> filter to select only docs where a particular field exists and has a value, or is undefined or has no value:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field &#39;foo&#39; has a value:
    { foo     =&gt; { exists  =&gt; 1 }}
    { foo     =&gt; { missing =&gt; 0 }}
    { -exists =&gt; &#39;foo&#39;           }

    # Field &#39;foo&#39; is undefined or has no value:
    { foo      =&gt; { missing =&gt; 1 }}
    { foo      =&gt; { exists  =&gt; 0 }}
    { -missing =&gt; &#39;foo&#39;           }
    { foo      =&gt; undef           }</pre>

<p>The <code>missing</code> filter also supports the <code>null_value</code> and <code>existence</code> parameters:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        foo     =&gt; {
            missing =&gt; {
                null_value =&gt; 1,
                existence  =&gt; 1,
            }
        }
    }</pre>

<p>OR</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    { -missing =&gt; {
        field      =&gt; &#39;foo&#39;,
        null_value =&gt; 1,
        existence  =&gt; 1,
    }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/missing-filter.html">Missing Filter</a> and <a href="http://www.elasticsearch.org/guide/reference/query-dsl/exists-filter.html">Exists Filter</a></p>

<h1 id="FULL-TEXT-SEARCH">FULL TEXT SEARCH</h1>

<p>*** Query context only ***</p>

<p>For most full text search queries, the <code>match</code> queries are what you want. These analyze the search terms, and look for documents that contain one or more of those terms. (See <a href="#EQUALITY-QUERIES-">&quot;EQUALITY (QUERIES)&quot;</a>).</p>

<h2 id="qs--query_string--not_qs--not_query_string">-qs | -query_string | -not_qs | -not_query_string</h2>

<p>However, there is a more advanced query string syntax (see <a href="http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/queryparsersyntax.html">Lucene Query Parser Syntax</a>) which understands search terms like:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">   perl AND python tag:recent &quot;this exact phrase&quot; -apple</pre>

<p>It is useful for &quot;power&quot; users, but has the disadvantage that, if the syntax is incorrect, ES throws an error. You can use <a href="./ElasticSearch::QueryParser">ElasticSearch::QueryParser</a> to fix any syntax errors.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # find docs whose &#39;title&#39; field matches &#39;this AND that&#39;
    { title =&gt; { qs           =&gt; &#39;this AND that&#39; }}
    { title =&gt; { query_string =&gt; &#39;this AND that&#39; }}

    # With other parameters
    { title =&gt; {
        field =&gt; {
            query                        =&gt; &#39;this that &#39;,
            default_operator             =&gt; &#39;AND&#39;,
            analyzer                     =&gt; &#39;default&#39;,
            allow_leading_wildcard       =&gt; 0,
            lowercase_expanded_terms     =&gt; 1,
            enable_position_increments   =&gt; 1,
            fuzzy_min_sim                =&gt; 0.5,
            fuzzy_prefix_length          =&gt; 2,
            fuzzy_rewrite                =&gt; &#39;constant_score_default&#39;,
            fuzzy_max_expansions         =&gt; 1024,
            lenient                      =&gt; 1,
            phrase_slop                  =&gt; 10,
            boost                        =&gt; 2,
            analyze_wildcard             =&gt; 1,
            auto_generate_phrase_queries =&gt; 0,
            rewrite                      =&gt; &#39;constant_score_default&#39;,
            minimum_should_match         =&gt; 3,
            quote_analyzer               =&gt; &#39;standard&#39;,
            quote_field_suffix           =&gt; &#39;.unstemmed&#39;
        }
    }}</pre>

<p>The unary form <code>-qs</code> or <code>-query_string</code> can be used when matching against multiple fields:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    { -qs =&gt; {
            query                        =&gt; &#39;this AND that &#39;,
            fields                       =&gt; [&#39;title&#39;,&#39;content&#39;],
            default_operator             =&gt; &#39;AND&#39;,
            analyzer                     =&gt; &#39;default&#39;,
            allow_leading_wildcard       =&gt; 0,
            lowercase_expanded_terms     =&gt; 1,
            enable_position_increments   =&gt; 1,
            fuzzy_min_sim                =&gt; 0.5,
            fuzzy_prefix_length          =&gt; 2,
            fuzzy_rewrite                =&gt; &#39;constant_score_default&#39;,
            fuzzy_max_expansions         =&gt; 1024,
            lenient                      =&gt; 1,
            phrase_slop                  =&gt; 10,
            boost                        =&gt; 2,
            analyze_wildcard             =&gt; 1,
            auto_generate_phrase_queries =&gt; 0,
            use_dis_max                  =&gt; 1,
            tie_breaker                  =&gt; 0.7,
            minimum_should_match         =&gt; 3,
            quote_analyzer               =&gt; &#39;standard&#39;,
            quote_field_suffix           =&gt; &#39;.unstemmed&#39;
    }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/query-string-query.html">Query-string Query</a></p>

<h2 id="mlt--not_mlt">-mlt | -not_mlt</h2>

<p>An <code>mlt</code> or <code>more_like_this</code> query finds documents that are &quot;like&quot; the specified text, where &quot;like&quot; means that it contains some or all of the specified terms.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo is like &quot;brown cow&quot;
    { foo =&gt; { mlt =&gt; &quot;brown cow&quot; }}

    # With other paramters:
    { foo =&gt; {
        mlt =&gt; {
            like_text               =&gt; &#39;brown cow&#39;,
            percent_terms_to_match  =&gt; 0.3,
            min_term_freq           =&gt; 2,
            max_query_terms         =&gt; 25,
            stop_words              =&gt; [&#39;the&#39;,&#39;and&#39;],
            min_doc_freq            =&gt; 5,
            max_doc_freq            =&gt; 1000,
            min_word_len            =&gt; 0,
            max_word_len            =&gt; 20,
            boost_terms             =&gt; 2,
            boost                   =&gt; 2.0,
            analyzer                =&gt; &#39;default&#39;
        }
    }}

    # multi fields
    { -mlt =&gt; {
        like_text               =&gt; &#39;brown cow&#39;,
        fields                  =&gt; [&#39;title&#39;,&#39;content&#39;]
        percent_terms_to_match  =&gt; 0.3,
        min_term_freq           =&gt; 2,
        max_query_terms         =&gt; 25,
        stop_words              =&gt; [&#39;the&#39;,&#39;and&#39;],
        min_doc_freq            =&gt; 5,
        max_doc_freq            =&gt; 1000,
        min_word_len            =&gt; 0,
        max_word_len            =&gt; 20,
        boost_terms             =&gt; 2,
        boost                   =&gt; 2.0,
        analyzer                =&gt; &#39;default&#39;
    }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/mlt-field-query.html">MLT Field Query</a> and <a href="http://www.elasticsearch.org/guide/reference/query-dsl/mlt-query.html">MLT Query</a></p>

<h2 id="flt--not_flt">-flt | -not_flt</h2>

<p>An <code>flt</code> or <code>fuzzy_like_this</code> query fuzzifies all specified terms, then picks the best <code>max_query_terms</code> differentiating terms. It is a combination of <code>fuzzy</code> with <code>more_like_this</code>.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo is fuzzily similar to &quot;brown cow&quot;
    { foo =&gt; { flt =&gt; &#39;brown cow }}

    # With other parameters:
    { foo =&gt; {
        flt =&gt; {
            like_text       =&gt; &#39;brown cow&#39;,
            ignore_tf       =&gt; 0,
            max_query_terms =&gt; 10,
            min_similarity  =&gt; 0.5,
            prefix_length   =&gt; 3,
            boost           =&gt; 2.0,
            analyzer        =&gt; &#39;default&#39;
        }
    }}

    # Multi-field
    flt =&gt; {
        like_text       =&gt; &#39;brown cow&#39;,
        fields          =&gt; [&#39;title&#39;,&#39;content&#39;],
        ignore_tf       =&gt; 0,
        max_query_terms =&gt; 10,
        min_similarity  =&gt; 0.5,
        prefix_length   =&gt; 3,
        boost           =&gt; 2.0,
        analyzer        =&gt; &#39;default&#39;
    }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/flt-field-query.html">FLT Field Query</a> and <a href="http://www.elasticsearch.org/guide/reference/query-dsl/flt-query.html">FLT Query</a></p>

<h1 id="PREFIX">PREFIX</h1>

<h2 id="PREFIX-QUERIES-">PREFIX (QUERIES)</h2>

<h3 id="phrase_prefix--not_phrase_prefix">^ | -phrase_prefix | -not_phrase_prefix</h3>

<p>These operators use the <code>match_phrase_prefix</code> query.</p>

<p>For <code>analyzed</code> fields, it analyzes the search terms, and does a <code>match_phrase</code> query, with a <code>prefix</code> query on the last term. Think &quot;auto-complete&quot;.</p>

<p>For <code>not_analyzed</code> fields, this behaves the same as the term-based <code>prefix</code> query.</p>

<p>For instance, given the phrase <code>The quick brown fox jumped over the lazy dog</code>:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # matches
    { content =&gt; { &#39;^&#39;             =&gt; &#39;qui&#39;}}
    { content =&gt; { &#39;^&#39;             =&gt; &#39;quick br&#39;}}
    { content =&gt; { &#39;phrase_prefix&#39; =&gt; &#39;quick brown f&#39;}}

    # doesn&#39;t match
    { content =&gt; { &#39;^&#39;             =&gt; &#39;quick fo&#39; }}
    { content =&gt; { &#39;phrase_prefix&#39; =&gt; &#39;fox brow&#39;}}</pre>

<p>With extra options</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    { content =&gt; {
        phrase_prefix =&gt; {
            query          =&gt; &quot;Brown Fo&quot;,
            slop           =&gt; 3,
            analyzer       =&gt; &#39;default&#39;,
            boost          =&gt; 3.0,
            max_expansions =&gt; 100,
        }
    }}</pre>

<p>See http://www.elasticsearch.org/guide/reference/query-dsl/match-query.html</p>

<h3 id="prefix--not_prefix">-prefix | -not_prefix</h3>

<p>The <code>prefix</code> query is a term-based query - no analysis takes place, even on analyzed fields. Generally you should use <code>^</code> instead.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field &#39;lang&#39; contains terms beginning with &#39;p&#39;
    { lang =&gt; { prefix =&gt; &#39;p&#39; }}

    # With extra options
    { lang =&gt; {
        &#39;prefix&#39; =&gt; {
            value   =&gt; &#39;p&#39;,
            boost   =&gt; 2,
            rewrite =&gt; &#39;constant_score_default&#39;,

        }
    }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/prefix-query.html">Prefix Query</a>.</p>

<h2 id="PREFIX-FILTERS-">PREFIX (FILTERS)</h2>

<h3 id="prefix--not_prefix1">^ | -prefix | -not_prefix</h3>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo contains a term which begins with &#39;bar&#39;
    { foo =&gt; { &#39;^&#39;      =&gt; &#39;bar&#39; }}
    { foo =&gt; { &#39;prefix&#39; =&gt; &#39;bar&#39; }}

    # Field foo contains a term which begins with &#39;bar&#39; or &#39;baz&#39;
    { foo =&gt; { &#39;^&#39;      =&gt; [&#39;bar&#39;,&#39;baz&#39;] }}
    { foo =&gt; { &#39;prefix&#39; =&gt; [&#39;bar&#39;,&#39;baz&#39;] }}

    # Field foo contains a term which begins with neither &#39;bar&#39; nor &#39;baz&#39;
    { foo =&gt; { &#39;not_prefix&#39; =&gt; [&#39;bar&#39;,&#39;baz&#39;] }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/prefix-filter.html">Prefix Filter</a></p>

<h1 id="WILDCARD-AND-FUZZY-QUERIES">WILDCARD AND FUZZY QUERIES</h1>

<p>*** Query context only ***</p>

<h2 id="wildcard--not_wildcard">* | -wildcard | -not_wildcard</h2>

<p>A <code>wildcard</code> is a term-based query (no analysis is applied), which does shell globbing to find matching terms. In other words <code>?</code> represents any single character, while <code>*</code> represents zero or more characters.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo matches &#39;f?ob*&#39;
    { foo =&gt; { &#39;*&#39;        =&gt; &#39;f?ob*&#39; }}
    { foo =&gt; { &#39;wildcard&#39; =&gt; &#39;f?ob*&#39; }}

    # with a boost:
    { foo =&gt; {
        &#39;*&#39; =&gt; { value =&gt; &#39;f?ob*&#39;, boost =&gt; 2.0 }
    }}
    { foo =&gt; {
        &#39;wildcard&#39; =&gt; {
            value   =&gt; &#39;f?ob*&#39;,
            boost   =&gt; 2.0,
            rewrite =&gt; &#39;constant_score_default&#39;,
        }
    }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/wildcard-query.html">Wildcard Query</a></p>

<h2 id="fuzzy--not_fuzzy">-fuzzy | -not_fuzzy</h2>

<p>A <code>fuzzy</code> query is a term-based query (ie no analysis is done) which looks for terms that are similar to the the provided terms, where similarity is based on the Levenshtein (edit distance) algorithm:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Field foo is similar to &#39;fonbaz&#39;
    { foo =&gt; { fuzzy =&gt; &#39;fonbaz&#39; }}

    # With other parameters:
    { foo =&gt; {
        fuzzy =&gt; {
            value           =&gt; &#39;fonbaz&#39;,
            boost           =&gt; 2.0,
            min_similarity  =&gt; 0.2,
            max_expansions  =&gt; 10,
            rewrite         =&gt; &#39;constant_score_default&#39;,
        }
    }}</pre>

<p>Normally, you should rather use either the <a href="#EQUALITY">&quot;EQUALITY&quot;</a> queries with the <code>fuzziness</code> parameter, or the <a href="#flt--not_flt">-flt</a> queries.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/fuzzy-query.html">Fuzzy Query</a>.</p>

<h1 id="COMBINING-QUERIES">COMBINING QUERIES</h1>

<p>*** Query context only ***</p>

<p>These constructs allow you to combine multiple queries.</p>

<h2 id="dis_max--dismax">-dis_max | -dismax</h2>

<p>While a <code>bool</code> query adds together the scores of the nested queries, a <code>dis_max</code> query uses the highest score of any matching queries.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Run the two queries and use the best score
    { -dismax =&gt; [
        { foo =&gt; &#39;bar&#39; },
        { foo =&gt; &#39;baz&#39; }
    ] }

    # With other parameters
    { -dismax =&gt; {
        queries =&gt; [
            { foo =&gt; &#39;bar&#39; },
            { foo =&gt; &#39;baz&#39; }
        ],
        tie_breaker =&gt; 0.5,
        boost =&gt; 2.0
    ] }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/dis-max-query.html">DisMax Query</a></p>

<h2 id="bool">-bool</h2>

<p>Normally, there should be no need to use a <code>bool</code> query directly, as these are autogenerated from eg <code>-and</code>, <code>-or</code> and <code>-not</code> constructs. However, if you need to pass any of the other parameters to a <code>bool</code> query, then you can do the following:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
       -bool =&gt; {
           must          =&gt; [{ foo =&gt; &#39;bar&#39; }],
           must_not      =&gt; { status =&gt; &#39;inactive&#39; },
           should        =&gt; [
                { tag    =&gt; &#39;perl&#39;   },
                { tag    =&gt; &#39;python&#39; },
                { tag    =&gt; &#39;ruby&#39; },
           ],
           minimum_number_should_match =&gt; 2,
           disable_coord =&gt; 1,
           boost         =&gt; 2
       }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/bool-query.html">Bool Query</a></p>

<h2 id="boosting">-boosting</h2>

<p>The <code>boosting</code> query can be used to &quot;demote&quot; results that match a given query. Unlike the <code>must_not</code> clause of a <code>bool</code> query, the query still matches, but the results are &quot;less relevant&quot;.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    { -boosting =&gt; {
        positive       =&gt; { title =&gt; &#39;apple pear&#39;     },
        negative       =&gt; { title =&gt; &#39;apple computer&#39; },
        negative_boost =&gt; 0.2
    }}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/boosting-query.html">Boosting Query</a></p>

<h2 id="custom_boost">-custom_boost</h2>

<p>The <code>custom_boost</code> query allows you to multiply the scores of another query by the specified boost factor. This is a bit different from a standard <code>boost</code>, which is normalized.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -custom_boost =&gt; {
            query           =&gt; { title =&gt; &#39;foo&#39; },
            boost_factor    =&gt; 3
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/custom-boost-factor-query.html">Custom Boost Factor Query</a>.</p>

<h1 id="NESTED-QUERIES-FILTERS">NESTED QUERIES/FILTERS</h1>

<p>Nested queries/filters allow you to run queries/filters on nested docs.</p>

<p>Normally, a doc like this would not allow you to associate the name <code>perl</code> with the number <code>5</code></p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">   {
       title:  &quot;my title&quot;,
       tags: [
        { name: &quot;perl&quot;,   num: 5},
        { name: &quot;python&quot;, num: 2}
       ]
   }</pre>

<p>However, if <code>tags</code> is mapped as a <code>nested</code> field, then you can run queries or filters on each sub-doc individually.</p>

<p>See <a href="http://github.com/elasticsearch/elasticsearch/issues/1095">Nested Mapping</a>, <a href="http://www.elasticsearch.org/guide/reference/mapping/nested-type.html">Nested Type</a> and <a href="http://www.elasticsearch.org/guide/reference/query-dsl/nested-query.html">Nested Query</a></p>

<h2 id="nested-QUERY-">-nested (QUERY)</h2>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -nested =&gt; {
            path        =&gt; &#39;tags&#39;,
            score_mode  =&gt; &#39;avg&#39;,
            _scope      =&gt; &#39;my_tags&#39;,
            query       =&gt; {
                &quot;tags.name&quot;  =&gt; &#39;perl&#39;,
                &quot;tags.num&quot;   =&gt; { gt =&gt; 2 },
            }
        }
    }</pre>

<p>See <a href="http://github.com/elasticsearch/elasticsearch/issues/1095">Nested Query</a></p>

<h2 id="nested-FILTER-">-nested (FILTER)</h2>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -nested =&gt; {
            path        =&gt; &#39;tags&#39;,
            score_mode  =&gt; &#39;avg&#39;,
            _cache      =&gt; 1,
            _name       =&gt; &#39;my_filter&#39;,
            filter      =&gt; {
                tags.name    =&gt; &#39;perl&#39;,
                tags.num     =&gt; { gt =&gt; 2},
            }
        }
    }</pre>

<p>See <a href="http://github.com/elasticsearch/elasticsearch/issues/1102">Nested Filter</a></p>

<h1 id="SCRIPTING">SCRIPTING</h1>

<p>ElasticSearch supports the use of scripts to customise query or filter behaviour. By default the query language is <code>mvel</code> but javascript, groovy, python and native java scripts are also supported.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/modules/scripting.html">Scripting</a> for more on scripting.</p>

<h2 id="custom_score">-custom_score</h2>

<p>*** Query context only ***</p>

<p>The <code>-custom_score</code> query allows you to customise the <code>_score</code> or relevance (and thus the order) of docs returned from a query.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -custom_score =&gt; {
            query  =&gt; { foo =&gt; &#39;bar&#39; },
            lang    =&gt; &#39;mvel&#39;,
            script =&gt; &quot;_score * doc[&#39;my_numeric_field&#39;].value / pow(param1, param2)&quot;
            params =&gt; {
                param1 =&gt; 2,
                param2 =&gt; 3.1
            },
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/custom-score-query.html">Custom Score Query</a></p>

<h2 id="custom_filters_score">-custom_filters_score</h2>

<p>*** Query context only ***</p>

<p>The <code>-custom_filters_score</code> query allows you to boost documents that match a filter, either with a <code>boost</code> parameter, or with a custom <code>script</code>.</p>

<p>This is a very powerful and efficient way to boost results which depend on matching unanalyzed fields, eg a <code>tag</code> or a <code>date</code>. Also, these filters can be cached.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -custom_filters_score =&gt; {
            query       =&gt; { foo =&gt; &#39;bar&#39; },
            score_mode  =&gt; &#39;first|max|total|avg|min|multiply&#39;, # default &#39;first&#39;
            max_boost   =&gt; 10,
            filters     =&gt; [
                {
                    filter =&gt; { tag =&gt; &#39;perl&#39; },
                    boost  =&gt; 2,
                },
                {
                    filter =&gt; { tag =&gt; &#39;python&#39; },
                    script =&gt; &#39;_score * my_boost&#39;,
                    params =&gt; { my_boost =&gt; 2},
                    lang   =&gt; &#39;mvel&#39;
                },
            ]
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/custom-filters-score-query.html">Custom Filters Score Query</a></p>

<h2 id="script">-script</h2>

<p>*** Filter context only ***</p>

<p>The <code>-script</code> filter allows you to use a script as a filter. Return a true value to indicate that the filter matches.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Filter docs whose field &#39;foo&#39; is greater than 5
    { -script =&gt; &quot;doc[&#39;foo&#39;].value &gt; 5 &quot; }

    # With other params
    {
        -script =&gt; {
            script =&gt; &quot;doc[&#39;foo&#39;].value &gt; minimum &quot;,
            params =&gt; { minimum =&gt; 5 },
            lang   =&gt; &#39;mvel&#39;
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/script-filter.html">Script Filter</a></p>

<h1 id="PARENT-CHILD">PARENT/CHILD</h1>

<p>Documents stored in ElasticSearch can be configured to have parent/child relationships.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/mapping/parent-field.html">Parent Field</a> for more.</p>

<h2 id="has_parent--not_has_parent">-has_parent | -not_has_parent</h2>

<p>Find child documents that have a parent document which matches a query.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Find parent docs whose children of type &#39;comment&#39; have the tag &#39;perl&#39;
    {
        -has_parent =&gt; {
            type   =&gt; &#39;comment&#39;,
            query  =&gt; { tag =&gt; &#39;perl&#39; },
            _scope =&gt; &#39;my_scope&#39;,
            boost  =&gt; 1,                    # Query context only
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/has-parent-query.html">Has Parent Query</a> and See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/has-parent-filter.html">Has Parent Filter</a>.</p>

<h2 id="has_child--not_has_child">-has_child | -not_has_child</h2>

<p>Find parent documents that have child documents which match a query.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Find parent docs whose children of type &#39;comment&#39; have the tag &#39;perl&#39;
    {
        -has_child =&gt; {
            type   =&gt; &#39;comment&#39;,
            query  =&gt; { tag =&gt; &#39;perl&#39; },
            _scope =&gt; &#39;my_scope&#39;,
            boost  =&gt; 1,                    # Query context only
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/has-child-query.html">Has Child Query</a> and See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/has-child-filter.html">Has Child Filter</a>.</p>

<h2 id="top_children">-top_children</h2>

<p>*** Query context only ***</p>

<p>The <code>top_children</code> query runs a query against the child docs, and aggregates the scores to find the parent docs whose children best match.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -top_children =&gt; {
            type                =&gt; &#39;blog_tag&#39;,
            query               =&gt; { tag =&gt; &#39;perl&#39; },
            score               =&gt; &#39;max&#39;,
            factor              =&gt; 5,
            incremental_factor  =&gt; 2,
            _scope              =&gt; &#39;my_scope&#39;
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/top-children-query.html">Top Children Query</a></p>

<h1 id="GEO-FILTERS">GEO FILTERS</h1>

<p>For all the geo filters, the <code>normalize</code> parameter defaults to <code>true</code>, meaning that the longitude value will be normalized to <code>-180</code> to <code>180</code> and the latitude value to <code>-90</code> to <code>90</code>.</p>

<h2 id="geo_distance--not_geo_distance">-geo_distance | -not_geo_distance</h2>

<p>*** Filter context only ***</p>

<p>The <code>geo_distance</code> filter will find locations within a certain distance of a given point:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        my_location =&gt; {
            -geo_distance     =&gt; {
                location      =&gt; { lat =&gt; 10, lon =&gt; 5 },
                distance      =&gt; &#39;5km&#39;,
                normalize     =&gt; 1 | 0,
                optimize_bbox =&gt; memory | indexed | none,
            }
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/geo-distance-filter.html">Geo Distance Filter</a></p>

<h2 id="geo_distance_range--not_geo_distance_range">-geo_distance_range | -not_geo_distance_range</h2>

<p>*** Filter context only ***</p>

<p>The <code>geo_distance_range</code> filter is similar to the <a href="#geo_distance--not_geo_distance">-geo_distance</a> filter, but expressed as a range:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        my_location =&gt; {
            -geo_distance       =&gt; {
                location        =&gt; { lat =&gt; 10, lon =&gt; 5 },
                from            =&gt; &#39;5km&#39;,
                to              =&gt; &#39;10km&#39;,
                include_lower   =&gt; 1 | 0,
                include_upper   =&gt; 0 | 1
                normalize       =&gt; 1 | 0,
                optimize_bbox   =&gt; memory | indexed | none,
            }
        }
    }</pre>

<p>or instead of <code>from</code>, <code>to</code>, <code>include_lower</code> and <code>include_upper</code> you can use <code>gt</code>, <code>gte</code>, <code>lt</code>, <code>lte</code>.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/geo-distance-range-filter.html">Geo Distance Range Filter</a></p>

<h2 id="geo_bounding_box--geo_bbox--not_geo_bounding_box--not_geo_bbox">-geo_bounding_box | -geo_bbox | -not_geo_bounding_box | -not_geo_bbox</h2>

<p>*** Filter context only ***</p>

<p>The <code>geo_bounding_box</code> filter finds points which lie within the given rectangle:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        my_location =&gt; {
            -geo_bbox =&gt; {
                top_left     =&gt; { lat =&gt; 9, lon =&gt; 4  },
                bottom_right =&gt; { lat =&gt; 10, lon =&gt; 5 },
                normalize    =&gt; 1 | 0,
                type         =&gt; memory | indexed
            }
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/geo-bounding-box-filter.html">Geo Bounding Box Filter</a></p>

<h2 id="geo_polygon--not_geo_polygon">-geo_polygon | -not_geo_polygon</h2>

<p>*** Filter context only ***</p>

<p>The <code>geo_polygon</code> filter is similar to the <a href="#geo_bounding_box--geo_bbox--not_geo_bounding_box--not_geo_bbox">-geo_bounding_box</a> filter, except that it allows you to specify a polygon instead of a rectangle:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        my_location =&gt; {
            -geo_polygon =&gt; [
                { lat =&gt; 40, lon =&gt; -70 },
                { lat =&gt; 30, lon =&gt; -80 },
                { lat =&gt; 20, lon =&gt; -90 },
            ]
        }
    }</pre>

<p>or:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        my_location =&gt; {
            -geo_polygon =&gt; {
                points  =&gt; [
                    { lat =&gt; 40, lon =&gt; -70 },
                    { lat =&gt; 30, lon =&gt; -80 },
                    { lat =&gt; 20, lon =&gt; -90 },
                ],
                normalize =&gt; 1 | 0,
            }
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/geo-polygon-filter.html">Geo Polygon Filter</a></p>

<h1 id="INDEX-TYPE-ID">INDEX/TYPE/ID</h1>

<h2 id="indices">-indices</h2>

<p>*** Query context only ***</p>

<p>To run a different query depending on the index name, you can use the <code>-indices</code> query:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -indices =&gt; {
            indices         =&gt; &#39;one&#39; | [&#39;one&#39;,&#39;two],
            query           =&gt; { status =&gt; &#39;active&#39; },
            no_match_query  =&gt; &#39;all&#39; | &#39;none&#39; | { another =&gt; query }
        }
    }</pre>

<p>The `no_match_query` will be run on any indices which don&#39;t appear in the specified list. It defaults to <code>all</code>, but can be set to <code>none</code> or to a full query.</p>

<p>See <a href="https://github.com/elasticsearch/elasticsearch/issues/1416">Indices Query</a> and <a href="https://github.com/elasticsearch/elasticsearch/issues/1492">no_match_query</a> for details.</p>

<h2 id="ids">-ids</h2>

<p>The <code>_id</code> field is not indexed by default, and thus isn&#39;t available for normal queries or filters</p>

<p>Returns docs with the matching <code>_id</code> or <code>_type</code>/<code>_id</code> combination:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # doc with ID 123
    { -ids =&gt; 123 }

    # docs with IDs 123 or 124
    { -ids =&gt; [123,124] }

    # docs of types &#39;blog&#39; or &#39;comment&#39; with IDs 123 or 124
    {
        -ids =&gt; {
            type    =&gt; [&#39;blog&#39;,&#39;comment&#39;],
            values  =&gt; [123,124]

        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/ids-query.html">IDs Query</a> abd <a href="http://www.elasticsearch.org/guide/reference/query-dsl/ids-filter.html">IDs Filter</a></p>

<h2 id="type">-type</h2>

<p>*** Filter context only ***</p>

<p>Filters docs with matching <code>_type</code> fields.</p>

<p>While the <code>_type</code> field is indexed by default, ElasticSearch provides the <code>type</code> filter which will work even if indexing of the <code>_type</code> field is disabled.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Filter docs of type &#39;comment&#39;
    { -type =&gt; &#39;comment&#39; }

    # Filter docs of type &#39;comment&#39; or &#39;blog&#39;
    { -type =&gt; [&#39;blog&#39;,&#39;comment&#39; ]}</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/type-filter.html">Type Filter</a></p>

<h1 id="LIMIT">LIMIT</h1>

<p>*** Filter context only ***</p>

<p>The <code>limit</code> filter limits the number of documents (per shard) to execute on:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        name    =&gt; &quot;Joe Bloggs&quot;,
        -filter =&gt; { -limit =&gt; 100       }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/limit-filter.html">Limit Filter</a></p>

<h1 id="NAMED-FILTERS">NAMED FILTERS</h1>

<p>ElasticSearch allows you to name filters, in which each search result will include a <code>matched_filters</code> array containing the names of all filters that matched.</p>

<h2 id="name--not_name">-name | -not_name</h2>

<p>*** Filter context only ***</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    { -name =&gt; {
        popular   =&gt; { user_rank =&gt; { &#39;gte&#39; =&gt; 10 }},
        unpopular =&gt; { user_rank =&gt; { &#39;lt&#39;  =&gt; 10 }},
    }}</pre>

<p>Multiple filters are joined with an <code>or</code> filter (as it doesn&#39;t make sense to join them with <code>and</code>).</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/api/search/named-filters.html">Named Filters</a> and <a href="#and--or--not">&quot;-and | -or | -not&quot;</a>.</p>

<h1 id="CACHING-FILTERS">CACHING FILTERS</h1>

<p>Part of the performance boost that you get when using filters comes from the ability to cache the results of those filters. However, it doesn&#39;t make sense to cache all filters by default.</p>

<h2 id="cache--nocache">-cache | -nocache</h2>

<p>*** Filter context only ***</p>

<p>If you would like to override the default caching, then you can use <code>-cache</code> or <code>-nocache</code>:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Don&#39;t cache the term filter for &#39;status&#39;
    {
        content =&gt; &#39;interesting post&#39;,
        -filter =&gt; {
            -nocache =&gt; { status =&gt; &#39;active&#39; }
        }
    }

    # Do cache the numeric range filter:
    {
        content =&gt; &#39;interesting post&#39;,
        -filter =&gt; {
            -cache =&gt; { created =&gt; {&#39;&gt;&#39; =&gt; &#39;2010-01-01&#39; } }
        }
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/">Query DSL</a> for more details about what is cached by default and what is not.</p>

<h2 id="cache_key">-cache_key</h2>

<p>It is also possible to use a name to identify a cached filter. For instance:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -cache_key =&gt; {
            friends =&gt; { person_id =&gt; [1,2,3] },
            enemies =&gt; { person_id =&gt; [4,5,6] },
        }
    }</pre>

<p>In the above example, the two filters will be joined by an <code>and</code> filter. The following example will have the two filters joined by an <code>or</code> filter:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        -cache_key =&gt; [
            friends =&gt; { person_id =&gt; [1,2,3] },
            enemies =&gt; { person_id =&gt; [4,5,6] },
        ]
    }</pre>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/index.html">_cache_key</a> for more details.</p>

<h1 id="RAW-ELASTICSEARCH-QUERY-DSL">RAW ELASTICSEARCH QUERY DSL</h1>

<p>Sometimes, instead of using the SearchBuilder syntax, you may want to revert to the raw Query DSL that ElasticSearch uses.</p>

<p>You can do this by passing a reference to a HASH ref, for instance:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    $sb-&gt;query({
        foo =&gt; 1,
        -filter =&gt; \{ term =&gt; { bar =&gt; 2 }}
    })</pre>

<p>Would result in:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        query =&gt; {
            filtered =&gt; {
                query =&gt; {
                    match =&gt; { foo =&gt; 1 }
                },
                filter =&gt; {
                    term =&gt; { bar =&gt; 2 }
                }
            }
        }
    }</pre>

<p>An example with OR&#39;ed filters:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    $sb-&gt;filter([
        foo =&gt; 1,
        \{ term =&gt; { bar =&gt; 2 }}
    ])</pre>

<p>Would result in:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        filter =&gt; {
            or =&gt; [
                { term =&gt; { foo =&gt; 1 }},
                { term =&gt; { bar =&gt; 2 }}
            ]
        }
    }</pre>

<p>An example with AND&#39;ed filters:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    $sb-&gt;filter({
        -and =&gt; [
            foo =&gt; 1 ,
            \{ term =&gt; { bar =&gt; 2 }}
        ]
    })</pre>

<p>Would result in:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    {
        filter =&gt; {
            and =&gt; [
                { term =&gt; { foo =&gt; 1 }},
                { term =&gt; { bar =&gt; 2 }}
            ]
        }
    }</pre>

<p>Wherever a filter or query is expected, passing a reference to a HASH-ref is accepted.</p>

<h1 id="ELASTICSEARCH-CONCEPTS">ELASTICSEARCH CONCEPTS</h1>

<h2 id="FILTERS-VS-QUERIES">FILTERS VS QUERIES</h2>

<p>ElasticSearch supports filters and queries:</p>

<ul>

<li><p>A filter just answers the question: &quot;Does this field match? Yes/No&quot;, eg:</p>

<ul>

<li><p>Does this document have the tag <code>&quot;beta&quot;</code>?</p>

</li>
<li><p>Was this document published in 2011?</p>

</li>
</ul>

</li>
<li><p>A query is used to calculate relevance ( known in ElasticSearch as <code>_score</code>):</p>

<ul>

<li><p>Give me all documents that include the keywords <code>&quot;Foo&quot;</code> and <code>&quot;Bar&quot;</code> and rank them in order of relevance.</p>

</li>
<li><p>Give me all documents whose <code>tag</code> field contains <code>&quot;perl&quot;</code> or <code>&quot;ruby&quot;</code> and rank documents that contain BOTH tags more highly.</p>

</li>
</ul>

</li>
</ul>

<p>Filters are lighter and faster, and the results can often be cached, but they don&#39;t contribute to the <code>_score</code> in any way.</p>

<p>Typically, most of your clauses will be filters, and just a few will be queries.</p>

<h2 id="TERMS-VS-TEXT">TERMS VS TEXT</h2>

<p>All data is stored in ElasticSearch as a <code>term</code>, which is an exact value. The term <code>&quot;Foo&quot;</code> is not the same as <code>&quot;foo&quot;</code>.</p>

<p>While this is useful for fields that have discreet values (eg <code>&quot;active&quot;</code>, <code>&quot;inactive&quot;</code>), it is not sufficient to support full text search.</p>

<p>ElasticSearch has to <i>analyze</i> text to convert it into terms. This applies both to the text that the stored document contains, and to the text that the user tries to search on.</p>

<p>The default analyzer will:</p>

<ul>

<li><p>split the text on (most) punctuation and remove that punctuation</p>

</li>
<li><p>lowercase each word</p>

</li>
<li><p>remove English stopwords</p>

</li>
</ul>

<p>For instance, <code>&quot;The 2 GREATEST widgets are foo-bar and fizz_buzz&quot;</code> would result in the terms <code> [2,&#39;greatest&#39;,&#39;widgets&#39;,&#39;foo&#39;,&#39;bar&#39;,&#39;fizz_buzz&#39;]</code>.</p>

<p>It is important that the same analyzer is used both for the stored text and for the search terms, otherwise the resulting terms may be different, and the query won&#39;t succeed.</p>

<p>For instance, a <code>term</code> query for <code>GREATEST</code> wouldn&#39;t work, but <code>greatest</code> would work. However, a <code>match</code> query for <code>GREATEST</code> would work, because the search text would be analyzed to produce the same terms that are stored in the index.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/index-modules/analysis/">Analysis</a> for the list of supported analyzers.</p>

<h2 id="match-QUERIES"><code>match</code> QUERIES</h2>

<p>ElasticSearch has a family of DWIM queries called <code>match</code> queries.</p>

<p>Their action depends upon how the field has been defined. If a field is <code>analyzed</code> (the default for string fields) then the <code>match</code> queries analyze the search terms before doing the search:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Convert &quot;Perl is GREAT&quot; to the terms &#39;perl&#39;,&#39;great&#39; and search
    # the &#39;content&#39; field for those terms

    { match: { content: &quot;Perl is GREAT&quot; }}</pre>

<p>If a field is <code>not_analyzed</code>, then it treats the search terms as a single term:</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    # Find all docs where the &#39;status&#39; field contains EXACTLY the term &#39;ACTIVE&#39;
    { match: { status: &quot;ACTIVE&quot; }}</pre>

<p>Filters, on the other hand, don&#39;t have full text queries - filters operate on simple terms instead.</p>

<p>See <a href="http://www.elasticsearch.org/guide/reference/query-dsl/match-query.html">Match Query</a> for more about match queries.</p>

<h1 id="AUTHOR">AUTHOR</h1>

<p>Clinton Gormley, <code>&lt;drtech at cpan.org&gt;</code></p>

<h1 id="BUGS">BUGS</h1>

<p>If you have any suggestions for improvements, or find any bugs, please report them to <a href="https://github.com/clintongormley/ElasticSearch-SearchBuilder/issues">https://github.com/clintongormley/ElasticSearch-SearchBuilder/issues</a>. I will be notified, and then you&#39;ll automatically be notified of progress on your bug as I make changes.</p>

<h1 id="TODO">TODO</h1>

<p>Add support for <code>span</code> queries.</p>

<h1 id="SUPPORT">SUPPORT</h1>

<p>You can find documentation for this module with the perldoc command.</p>

<pre class="brush: pl; class-name: 'highlight'; toolbar: false; gutter: false">    perldoc ElasticSearch::SearchBuilder</pre>

<p>You can also look for information at: <a href="http://www.elasticsearch.org">http://www.elasticsearch.org</a></p>

<h1 id="ACKNOWLEDGEMENTS">ACKNOWLEDGEMENTS</h1>

<p>Thanks to SQL::Abstract for providing the inspiration and some of the internals.</p>

<h1 id="LICENSE-AND-COPYRIGHT">LICENSE AND COPYRIGHT</h1>

<p>Copyright 2011 Clinton Gormley.</p>

<p>This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.</p>

<p>See <a href="http://dev.perl.org/licenses/">http://dev.perl.org/licenses/</a> for more information.</p>


</div>
</body>
</html>


