<commit_before>[[query-dsl-percolate-query]]
=== Percolate Query

The `percolate` query can be used to match queries
stored in an index. The `percolate` query itself
contains the document that will be used as query
to match with the stored queries.

[float]
=== Sample Usage

Create an index with two fields:

[source,js]
--------------------------------------------------
PUT /my-index
{
    "mappings": {
        "doc": {
            "properties": {
                "message": {
                    "type": "text"
                },
                "query": {
                    "type": "percolator"
                }
            }
        }
    }
}
--------------------------------------------------
// CONSOLE

The `message` field is the field used to preprocess the document defined in
the `percolator` query before it gets indexed into a temporary index.

The `query` field is used for indexing the query documents. It will hold a
json object that represents an actual Elasticsearch query. The `query` field
has been configured to use the <<percolator,percolator field type>>. This field
type understands the query dsl and stored the query in such a way that it can be
used later on to match documents defined on the `percolate` query.

Register a query in the percolator:

[source,js]
--------------------------------------------------
PUT /my-index/doc/1?refresh
{
    "query" : {
        "match" : {
            "message" : "bonsai tree"
        }
    }
}
--------------------------------------------------
// CONSOLE
// TEST[continued]

Match a document to the registered percolator queries:

[source,js]
--------------------------------------------------
GET /my-index/_search
{
    "query" : {
        "percolate" : {
            "field" : "query",
            "document" : {
                "message" : "A new bonsai tree in the office"
            }
        }
    }
}
--------------------------------------------------
// CONSOLE
// TEST[continued]

The above request will yield the following response:

[source,js]
--------------------------------------------------
{
  "took": 13,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped" : 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.5753642,
    "hits": [
      { <1>
        "_index": "my-index",
        "_type": "doc",
        "_id": "1",
        "_score": 0.5753642,
        "_source": {
          "query": {
            "match": {
              "message": "bonsai tree"
            }
          }
        },
        "fields" : {
          "_percolator_document_slot" : [0] <2>
        }
      }
    ]
  }
}
--------------------------------------------------
// TESTRESPONSE[s/"took": 13,/"took": "$body.took",/]

<1> The query with id `1` matches our document.
<2> The `_percolator_document_slot` field indicates which document has matched with this query.
    Useful when percolating multiple document simultaneously.

[float]
==== Parameters

The following parameters are required when percolating a document:

[horizontal]
`field`:: The field of type `percolator` that holds the indexed queries. This is a required parameter.
`name`:: The suffix to be used for the `_percolator_document_slot` field in case multiple `percolate` queries have been specified.
         This is an optional parameter.
`document`:: The source of the document being percolated.
`documents`:: Like the `document` parameter, but accepts multiple documents via a json array.
`document_type`:: The type / mapping of the document being percolated. This setting is deprecated and only required for indices created before 6.0

Instead of specifying the source of the document being percolated, the source can also be retrieved from an already
stored document. The `percolate` query will then internally execute a get request to fetch that document.

In that case the `document` parameter can be substituted with the following parameters:

[horizontal]
`index`:: The index the document resides in. This is a required parameter.
`type`:: The type of the document to fetch. This is a required parameter.
`id`:: The id of the document to fetch. This is a required parameter.
`routing`:: Optionally, routing to be used to fetch document to percolate.
`preference`:: Optionally, preference to be used to fetch document to percolate.
`version`:: Optionally, the expected version of the document to be fetched.

[float]
==== Percolating multiple documents

The `percolate` query can match multiple documents simultaneously with the indexed percolator queries.
Percolating multiple documents in a single request can improve performance as queries only need to be parsed and
matched once instead of multiple times.

The `_percolator_document_slot` field that is being returned with each matched percolator query is important when percolating
multiple documents simultaneously. It indicates which documents matched with a particular percolator query. The numbers
correlate with the slot in the `documents` array specified in the `percolate` query.

[source,js]
--------------------------------------------------
GET /my-index/_search<commit_msg>docs: add paragraph about using `percolate` query in a filter context<commit_after>[[query-dsl-percolate-query]]
=== Percolate Query

The `percolate` query can be used to match queries
stored in an index. The `percolate` query itself
contains the document that will be used as query
to match with the stored queries.

[float]
=== Sample Usage

Create an index with two fields:

[source,js]
--------------------------------------------------
PUT /my-index
{
    "mappings": {
        "doc": {
            "properties": {
                "message": {
                    "type": "text"
                },
                "query": {
                    "type": "percolator"
                }
            }
        }
    }
}
--------------------------------------------------
// CONSOLE

The `message` field is the field used to preprocess the document defined in
the `percolator` query before it gets indexed into a temporary index.

The `query` field is used for indexing the query documents. It will hold a
json object that represents an actual Elasticsearch query. The `query` field
has been configured to use the <<percolator,percolator field type>>. This field
type understands the query dsl and stored the query in such a way that it can be
used later on to match documents defined on the `percolate` query.

Register a query in the percolator:

[source,js]
--------------------------------------------------
PUT /my-index/doc/1?refresh
{
    "query" : {
        "match" : {
            "message" : "bonsai tree"
        }
    }
}
--------------------------------------------------
// CONSOLE
// TEST[continued]

Match a document to the registered percolator queries:

[source,js]
--------------------------------------------------
GET /my-index/_search
{
    "query" : {
        "percolate" : {
            "field" : "query",
            "document" : {
                "message" : "A new bonsai tree in the office"
            }
        }
    }
}
--------------------------------------------------
// CONSOLE
// TEST[continued]

The above request will yield the following response:

[source,js]
--------------------------------------------------
{
  "took": 13,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped" : 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.5753642,
    "hits": [
      { <1>
        "_index": "my-index",
        "_type": "doc",
        "_id": "1",
        "_score": 0.5753642,
        "_source": {
          "query": {
            "match": {
              "message": "bonsai tree"
            }
          }
        },
        "fields" : {
          "_percolator_document_slot" : [0] <2>
        }
      }
    ]
  }
}
--------------------------------------------------
// TESTRESPONSE[s/"took": 13,/"took": "$body.took",/]

<1> The query with id `1` matches our document.
<2> The `_percolator_document_slot` field indicates which document has matched with this query.
    Useful when percolating multiple document simultaneously.

[float]
==== Parameters

The following parameters are required when percolating a document:

[horizontal]
`field`:: The field of type `percolator` that holds the indexed queries. This is a required parameter.
`name`:: The suffix to be used for the `_percolator_document_slot` field in case multiple `percolate` queries have been specified.
         This is an optional parameter.
`document`:: The source of the document being percolated.
`documents`:: Like the `document` parameter, but accepts multiple documents via a json array.
`document_type`:: The type / mapping of the document being percolated. This setting is deprecated and only required for indices created before 6.0

Instead of specifying the source of the document being percolated, the source can also be retrieved from an already
stored document. The `percolate` query will then internally execute a get request to fetch that document.

In that case the `document` parameter can be substituted with the following parameters:

[horizontal]
`index`:: The index the document resides in. This is a required parameter.
`type`:: The type of the document to fetch. This is a required parameter.
`id`:: The id of the document to fetch. This is a required parameter.
`routing`:: Optionally, routing to be used to fetch document to percolate.
`preference`:: Optionally, preference to be used to fetch document to percolate.
`version`:: Optionally, the expected version of the document to be fetched.

[float]
==== Percolating in a filter context

In case you are not interested in the score, better performance can be expected by wrapping
the percolator query in a `bool` query's filter clause or in a `constant_score` query:

[source,js]
--------------------------------------------------
GET /my-index/_search
{
    "query" : {
        "constant_score": {
            "filter": {
                "percolate" : {
                    "field" : "query",
                    "document" : {
                        "message" : "A new bonsai tree in the office"
                    }
                }
            }
        }
    }
}
--------------------------------------------------
// CONSOLE
// TEST[continued]

At index time terms are extracted from the percolator query and the percolator
can often determine whether a query matches just by looking at those extracted
terms. However, computing scores requires to deserialize each matching query
and run it against the percolated document, which is a much more expensive
operation. Hence if computing scores is not required the `percolate` query
should be wrapped in a `constant_score` query or a `bool` query's filter clause.

Note that the `percolate` query never gets cached by the query cache.

[float]
==== Percolating multiple documents

The `percolate` query can match multiple documents simultaneously with the indexed percolator queries.
Percolating multiple documents in a single request can improve performance as queries only need to be parsed and
matched once instead of multiple times.

The `_percolator_document_slot` field that is being returned with each matched percolator query is important when percolating
multiple documents simultaneously. It indicates which documents matched with a particular percolator query. The numbers
correlate with the slot in the `documents` array specified in the `percolate` query.

[source,js]
--------------------------------------------------
GET /my-index/_search
{'fraction_non_alphanumeric': 0.16694015027204423, 'fraction_numerical': 0.006045427066240608, 'mean_word_length': 2.0912973838761344, 'pattern_counts': {'":': 56, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7653062', 'n_tokens_mistral': 3041, 'n_tokens_neox': 2905, 'n_words': 1280}