Elastic::Manual::QueryDSL::Filters - Overview of the filters available in ElasticSearch
version 0.02
Filters are pretty self explanatory. We present some of the most common filters below. To understand more about what filters are available, and how they work, you should read the about the Query DSL on http://www.elasticsearch.org/guide/reference/query-dsl/ and, optionally, the ElasticSearch::SearchBuilder syntax. All examples will be given first in the SearchBuilder syntax (with filterb()), then in the native Query DSL.
filterb()
It is important to remember that filters work on exact values. So "Foo" will not match "FOO".
"Foo"
"FOO"
While you can use a filter on an analyzed text field, you need to filter on the actual terms that are stored in that field. For instance, if the attribute value is: "A quick Brown FOX", it might be analyzed to the terms ['quick','brown','fox']. Filtering on "Brown" will not work. You need to use the actual term: "brown" instead.
"A quick Brown FOX"
['quick','brown','fox']
"Brown"
"brown"
Alternatively, if you need the analysis phase, you can use a query as a filter.
# WHERE status = 'active' $view->filterb( status => 'active' ); # WHERE count = 5 $view->filterb( count => 5 ); # WHERE tags IN ('perl','python') $view->filterb( tags => [ 'perl', 'python' ]);
See "EQUALITY (FILTERS)" in ElasticSearch::SearchBuilder.
# WHERE status = 'active' $view->filter( term => { status => 'active' } ); # WHERE count = 5 $view->filter( term => { count => 5 ); # WHERE tags IN ('perl','python') $view->filter( terms => { tag => ['perl', 'python' ]})
See http://www.elasticsearch.org/guide/reference/query-dsl/term-filter.html and http://www.elasticsearch.org/guide/reference/query-dsl/terms-filter.html.
# WHERE date BETWEEN '2012-01-01' AND '2013-01-01' $view->filterb( date => { gte => '2012-01-01', lt => '2013-01-01' } );
For ranges on fields that have many values:
$view->filterb( timestamp => { '>=' => '2012-01-01', '<' => '2013-01-01' } );
See "RANGES" in ElasticSearch::SearchBuilder
# WHERE date BETWEEN '2012-01-01' AND '2013-01-01' $view->filter( range => { date => { gte => '2012-01-01', lt => '2013-01-01' } } );
See http://www.elasticsearch.org/guide/reference/query-dsl/range-filter.html
$view->filter( numeric_range => { timestamp => { gte => '2012-01-01', lt => '2013-01-01' } } );
See http://www.elasticsearch.org/guide/reference/query-dsl/numeric-range-filter.html
See "AND|OR LOGIC" in ElasticSearch::SearchBuilder
# WHERE status = 'active' AND count > 5 $view->filterb( status => 'active', count => { gt => 5 } );
# WHERE status = 'active' OR count > 5 $view->filterb([ status => 'active', count => { gt => 5 } ]);
# WHERE status <> 'active' $view->filterb( status => { '!=' => 'active' }); # WHERE tags NOT IN ('perl','python') $view->filterb( tags => { '!=' => ['perl', 'python'] }); # WHERE NOT ( x = 1 AND y = 2 ) $view->filterb( -not => { x => 1, y => 2 }); # WHERE NOT ( x = 1 OR y = 2 ) $view->filterb( -not => [ x => 1, y => 2 ]);
# WHERE status = 'active' AND count > 5 $view->filter( and => [ { term => { status => 'active' }}, { range => { count => { gt => 5 }}} ] );
See http://www.elasticsearch.org/guide/reference/query-dsl/and-filter.html
# WHERE status = 'active' OR count > 5 $view->filter( or => [ { term => { status => 'active' }}, { range => { count => { gt => 5 }}} ] );
See http://www.elasticsearch.org/guide/reference/query-dsl/or-filter.html
# WHERE status <> 'active' $view->filter( not => { term => { status => 'active' }}); # WHERE tags NOT IN ('perl','python') $view->filter( not => { terms => { tags => ['perl', 'python'] }}); # WHERE NOT ( x = 1 AND y = 2 ) $view->filter( not => { and => [ { term => { x => 1 }}, { term => { y => 2 }} ] } ); # WHERE NOT ( x = 1 OR y = 2 ) $view->filter( not => { or => [ { term => { x => 1 }}, { term => { y => 2 }} ] } );
See http://www.elasticsearch.org/guide/reference/query-dsl/not-filter.html
# WHERE status IS NULL $view->filterb( -missing => 'status' ); $view->filterb( status => undef ); # WHERE status IS NOT NULL $view->filterb( -exists => 'status' );
See "MISSING OR NULL VALUES" in ElasticSearch::SearchBuilder.
# WHERE status IS NULL $view->filter( missing => { field => 'status' }); # WHERE status IS NOT NULL $view->filter( exists => { field => 'status' });
See http://www.elasticsearch.org/guide/reference/query-dsl/missing-filter.html and http://www.elasticsearch.org/guide/reference/query-dsl/exists-filter.html.
Warning: The prefix filter does not peform well. First it has to load all terms into memory to find those that begin with the prefix. Then it searches on all of those terms.
If you find yourself wanting to use a prefix filter, then you should rather use the edge_ngram token filter to prepare your field correctly for partial matching (eg "ABC" becomes "A", "AB", "ABC"), and use simple "Equality" instead.
"ABC"
"A"
"AB"
# WHERE code LIKE 'XYZ_%' $view->filterb( code => { '^' => 'XYZ_' }); $view->filterb( code => { prefix => 'XYZ_' });
See "PREFIX (FILTERS)" in ElasticSearch::SearchBuilder.
# WHERE code LIKE 'XYZ_%' $view->filter( prefix => { code => 'XYZ_' });
See http://www.elasticsearch.org/guide/reference/query-dsl/prefix-filter.html.
# where "point" is less than 50km from (lat:10, lon:5) $view->filterb( point => { -geo_distance => { location => { lat => 10, lon => 5 }, distance => '50km' } } );
See:
Geo-distance: "-geo_distance | -not_geo_distance" in ElasticSearch::SearchBuilder
Geo-distance ranges: "-geo_distance_range | -not_geo_distance_range" in ElasticSearch::SearchBuilder.
Geo-bounding boxes: "-geo_bounding_box | -geo_bbox | -not_geo_bounding_box | -not_geo_bbox" in ElasticSearch::SearchBuilder.
Geo-polygons: "-geo_polygon | -not_geo_polygon" in ElasticSearch::SearchBuilder.
$view->filter( geo_distance => { distance => '50km', point => { lat => 10, lon => 5 } } );
Geo-distance: http://www.elasticsearch.org/guide/reference/query-dsl/geo-distance-filter.html
Geo-distance ranges: http://www.elasticsearch.org/guide/reference/query-dsl/geo-distance-range-filter.html.
Geo-bounding boxes: http://www.elasticsearch.org/guide/reference/query-dsl/geo-bounding-box-filter.html.
Geo-polygons: http://www.elasticsearch.org/guide/reference/query-dsl/geo-polygon-filter.html.
# WHERE doc.id = 1 $view->filterb( _id => 1 ); # WHERE doc.id IN (1,2,3) $view->filterb( _id => [1,2,3] ); # WHERE doc.id in (1,2,3) AND doc.type in ('user','post') $view->filterb( _id => [1,2,3], _type => ['user','post'] );
Assuming that a document has an Elastic::Doc attribute user:
user
# WHERE user_id = 1 $view->filterb( 'user.uid.id' => 1 ); # WHERE user_type = 'user' $view->filterb( 'user.uid.type' => 'user' );
# WHERE doc.id = 1 $view->filter( term => { _id => 1 } ); # WHERE doc.id IN (1,2,3) $view->filter( terms => { _id => [1,2,3] }); # WHERE doc.id in (1,2,3) AND doc.type in ('user','post') $view->filter( and => [ { terms => { _id => [1,2,3] }}, { terms => { _type => ['user','post'] }} ] );
# WHERE user_id = 1 $view->filter( term => { 'user.uid.id' => 1 }); # WHERE user_type = 'user' $view->filter( term => { 'user.uid.type' => 'user' });
Script filters can be written in mvel, javascript, python or java. See http://www.elasticsearch.org/guide/reference/modules/scripting. Scripts can be useful, but they do have a performance impact, so consider whether you really need a script, or whether you could achieve your goals by indexing a field differently.
$view->filterb( -script => { script => "doc['foo'].value > minimum", params => { minimum => 5 }, } );
See "-script" in ElasticSearch::SearchBuilder.
$view->filter( script => { script => "doc['foo'].value > minimum", params => { minimum => 5 }, } );
See http://www.elasticsearch.org/guide/reference/query-dsl/script-filter.html
If you need to use a query as a filter (ie it can do full text matching, but won't be scored), you can embed a query in a filter:
# WHERE status = 'active' AND matches(title, 'perl python') $view->filterb( status => 'active', -query => { title => 'perl python' } );
See "QUERY / FILTER CONTEXT" in ElasticSearch::SearchBuilder.
# WHERE status = 'active' AND matches(title, 'perl python') $view->filter( and => [ { term => { status => 'active' }}, { query => { text => { title => 'perl python' } }} ] );
See http://www.elasticsearch.org/guide/reference/query-dsl/query-filter.html.
Parent-child relationships are not yet supported natively in Elastic::Model. They will be soon.
In the meantime, see:
"PARENT/CHILD" in ElasticSearch::SearchBuilder
http://www.elasticsearch.org/guide/reference/query-dsl/has-child-filter.html
See Elastic::Manual::QueryDSL::Nested.
Elastic::Manual::QueryDSL
Elastic::Manual::QueryDSL::Queries
Clinton Gormley <drtech@cpan.org>
This software is copyright (c) 2012 by Clinton Gormley.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Elastic::Model, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Elastic::Model
CPAN shell
perl -MCPAN -e shell install Elastic::Model
For more information on module installation, please visit the detailed CPAN module installation guide.