- Elasticsearch Guide: other versions:
- Getting Started
- Setup
- Breaking changes
- API Conventions
- Document APIs
- Search APIs
- Search
- URI Search
- Request Body Search
- Search Template
- Search Shards API
- Aggregations
- Min Aggregation
- Max Aggregation
- Sum Aggregation
- Avg Aggregation
- Stats Aggregation
- Extended Stats Aggregation
- Value Count Aggregation
- Percentiles Aggregation
- Percentile Ranks Aggregation
- Cardinality Aggregation
- Geo Bounds Aggregation
- Top hits Aggregation
- Scripted Metric Aggregation
- Global Aggregation
- Filter Aggregation
- Filters Aggregation
- Missing Aggregation
- Nested Aggregation
- Reverse nested Aggregation
- Children Aggregation
- Terms Aggregation
- Significant Terms Aggregation
- Range Aggregation
- Date Range Aggregation
- IPv4 Range Aggregation
- Histogram Aggregation
- Date Histogram Aggregation
- Geo Distance Aggregation
- GeoHash grid Aggregation
- Facets
- Suggesters
- Multi Search API
- Count API
- Search Exists API
- Validate API
- Explain API
- Percolator
- More Like This API
- Field stats API
- Indices APIs
- Create Index
- Delete Index
- Get Index
- Indices Exists
- Open / Close Index API
- Put Mapping
- Get Mapping
- Get Field Mapping
- Types Exists
- Delete Mapping
- Index Aliases
- Update Indices Settings
- Get Settings
- Analyze
- Index Templates
- Warmers
- Status
- Indices Stats
- Indices Segments
- Indices Recovery
- Clear Cache
- Flush
- Refresh
- Optimize
- Shadow replica indices
- Upgrade
- cat APIs
- Cluster APIs
- Query DSL
- Queries
- Match Query
- Multi Match Query
- Bool Query
- Boosting Query
- Common Terms Query
- Constant Score Query
- Dis Max Query
- Filtered Query
- Fuzzy Like This Query
- Fuzzy Like This Field Query
- Function Score Query
- Fuzzy Query
- GeoShape Query
- Has Child Query
- Has Parent Query
- Ids Query
- Indices Query
- Match All Query
- More Like This Query
- Nested Query
- Prefix Query
- Query String Query
- Simple Query String Query
- Range Query
- Regexp Query
- Span First Query
- Span Multi Term Query
- Span Near Query
- Span Not Query
- Span Or Query
- Span Term Query
- Term Query
- Terms Query
- Top Children Query
- Wildcard Query
- Minimum Should Match
- Multi Term Query Rewrite
- Template Query
- Filters
- And Filter
- Bool Filter
- Exists Filter
- Geo Bounding Box Filter
- Geo Distance Filter
- Geo Distance Range Filter
- Geo Polygon Filter
- GeoShape Filter
- Geohash Cell Filter
- Has Child Filter
- Has Parent Filter
- Ids Filter
- Indices Filter
- Limit Filter
- Match All Filter
- Missing Filter
- Nested Filter
- Not Filter
- Or Filter
- Prefix Filter
- Query Filter
- Range Filter
- Regexp Filter
- Script Filter
- Term Filter
- Terms Filter
- Type Filter
- Queries
- Mapping
- Analysis
- Analyzers
- Tokenizers
- Token Filters
- Standard Token Filter
- ASCII Folding Token Filter
- Length Token Filter
- Lowercase Token Filter
- Uppercase Token Filter
- NGram Token Filter
- Edge NGram Token Filter
- Porter Stem Token Filter
- Shingle Token Filter
- Stop Token Filter
- Word Delimiter Token Filter
- Stemmer Token Filter
- Stemmer Override Token Filter
- Keyword Marker Token Filter
- Keyword Repeat Token Filter
- KStem Token Filter
- Snowball Token Filter
- Phonetic Token Filter
- Synonym Token Filter
- Compound Word Token Filter
- Reverse Token Filter
- Elision Token Filter
- Truncate Token Filter
- Unique Token Filter
- Pattern Capture Token Filter
- Pattern Replace Token Filter
- Trim Token Filter
- Limit Token Count Token Filter
- Hunspell Token Filter
- Common Grams Token Filter
- Normalization Token Filter
- CJK Width Token Filter
- CJK Bigram Token Filter
- Delimited Payload Token Filter
- Keep Words Token Filter
- Keep Types Token Filter
- Classic Token Filter
- Apostrophe Token Filter
- Character Filters
- ICU Analysis Plugin
- Modules
- Index Modules
- Testing
- Glossary of terms
WARNING: Version 1.7 of Elasticsearch has passed its EOL date.
This documentation is no longer being maintained and may be removed. If you are running this version, we strongly advise you to upgrade. For the latest information, see the current release documentation.
Facets
editFacets
editFacets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead.
The usual purpose of a full-text search engine is to return a small number of documents matching your query.
Facets provide aggregated data based on a search query. In the simplest case, a terms facet can return facet counts for various facet values for a specific field. Elasticsearch supports more facet implementations, such as statistical or date histogram facets.
The field used for facet calculations must be of type numeric, date/time or be analyzed as a single token — see the Mapping guide for details on the analysis process.
You can give the facet a custom name and return multiple facets in one request.
Let’s try it out with a simple example. Suppose we have a number of
articles with a field called tags
, preferably analyzed with the
keyword
analyzer. The facet aggregation will return counts for the most popular
tags across the documents matching your query — or across all documents
in the index.
We will store some example data first:
curl -X DELETE "http://localhost:9200/articles" curl -X POST "http://localhost:9200/articles/article" -d '{"title" : "One", "tags" : ["foo"]}' curl -X POST "http://localhost:9200/articles/article" -d '{"title" : "Two", "tags" : ["foo", "bar"]}' curl -X POST "http://localhost:9200/articles/article" -d '{"title" : "Three", "tags" : ["foo", "bar", "baz"]}'
Now, let’s query the index for articles beginning with letter T
and retrieve a
terms facet
for the tags
field. We will name the facet simply: tags.
curl -X POST "http://localhost:9200/articles/_search?pretty=true" -d ' { "query" : { "query_string" : {"query" : "T*"} }, "facets" : { "tags" : { "terms" : {"field" : "tags"} } } } '
This request will return articles Two
and Three
(because
they match our query), as well as the tags
facet:
"facets" : { "tags" : { "_type" : "terms", "missing" : 0, "total": 5, "other": 0, "terms" : [ { "term" : "foo", "count" : 2 }, { "term" : "bar", "count" : 2 }, { "term" : "baz", "count" : 1 } ] } }
In the terms
array, relevant terms and counts are returned. You’ll
probably want to display these to your users. The facet returns several
important counts:
-
missing
: The number of documents which have no value for the faceted field
-
total
: The total number of terms in the facet
-
other
: The number of terms not included in the returned facet (effectivelyother
=total
-terms
)
Notice, that the counts are scoped to the current query: foo is counted only twice (not three times), bar is counted twice and baz once. Also note that terms are counted once per document, even if the occur more frequently in that document.
That’s because the primary purpose of facets is to enable faceted navigation, allowing the user to refine her query based on the insight from the facet, i.e. restrict the search to a specific category, price or date range. Facets can be used, however, for other purposes: computing histograms, statistical aggregations, and more. See the blog about data visualization for inspiration.
Scope
editAs we have already mentioned, facet computation is restricted to the
scope of the current query, called main
, by default. Facets can be
computed within the global
scope as well, in which case it will return
values computed across all documents in the index:
There’s one important distinction to keep in mind. While search queries restrict both the returned documents and facet counts, search filters restrict only returned documents — but not facet counts.
If you need to restrict both the documents and facets, and you’re not willing or able to use a query, you may use a facet filter.
Facet Filter
editAll facets can be configured with an additional filter (explained in the Query DSL section), which will reduce the documents they use for computing results. An example with a term filter:
{ "facets" : { "<FACET NAME>" : { "<FACET TYPE>" : { ... }, "facet_filter" : { "term" : { "user" : "kimchy"} } } } }
Note that this is different from a facet of the filter type.
Facets with the nested types
editNested mapping allows for better support for "inner" documents faceting, especially when it comes to multi valued key and value facets (like histograms, or term stats).
What is it good for? First of all, this is the only way to use facets on nested documents once they are used (possibly for other reasons). But, there is also facet specific reason why nested documents can be used, and that’s the fact that facets working on different key and value field (like term_stats, or histogram) can now support cases where both are multi valued properly.
For example, let’s use the following mapping:
{ "type1" : { "properties" : { "obj1" : { "type" : "nested" } } } }
And, here is a sample data:
{ "obj1" : [ { "name" : "blue", "count" : 4 }, { "name" : "green", "count" : 6 } ] }
All Nested Matching Root Documents
editAnother option is to run the facet on all the nested documents matching the root objects that the main query will end up producing. For example:
{ "query": { "match_all": {} }, "facets": { "facet1": { "terms_stats": { "key_field" : "name", "value_field": "count" }, "nested": "obj1" } } }
The nested
element provides the path to the nested document (can be a
multi level nested docs) that will be used.
Facet filter allows you to filter your facet on the nested object level.
It is important that these filters match on the nested object level and
not on the root document level. In the following example the
terms_stats
only applies on nested objects with the name blue.
{ "query": { "match_all": {} }, "facets": { "facet1": { "terms_stats": { "key_field" : "name", "value_field": "count" }, "nested": "obj1", "facet_filter" : { "term" : {"name" : "blue"} } } } }