From 1277c7d81cfa1ec3e2816858fa93846dd56794c2 Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Tue, 28 Mar 2017 13:00:36 -0400 Subject: [PATCH] Bug 18345 - Add a more ES based query builder This moves some code from bug 14567 --- Koha/SearchEngine/Elasticsearch/QueryBuilder.pm | 90 +++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm index f9364e3..c963b79 100644 --- a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm +++ b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm @@ -48,6 +48,96 @@ use URI::Escape; use C4::Context; + =head2 build_term_query + + my $query = $builder->build_query($search, %options); + +C<$search> is an arrayref where each element is a hashref containing +a part of the search. + +The hashref must contain a 'term', which is the string, and may contain other +things to adjust how the search is performed: + +=over 4 + +=item field + +the field to search on, as defined in the C table. If +unspecified, all fields will be searched over. + +=item exact + +do an exact, literal, phrase match rather than a tokenised search. This will +also ignore things like truncation and fuzziness. + +=back + +The C<%options> may be: + +=over 4 + +=item and_or + +either "and" or "or", and determines how multiple terms are combined. Default +is "and." + +=back + +=head3 Returns + +a query structure intended to be passed to elasticsearch. + +=head3 Note + +This is pretty limited, it's intended that more options be added as necessary +to support new functionality. + +=head3 Note 2 + +This ultimately ought to be replaced with a query parser driver, but that code +is not documented so it'll take a while to figure out. + +=cut + +sub build_term_query { + my ( $self, $search, %options ) = @_; + + my @match_parts; + + foreach my $s (@$search) { + my ( $m_type, $f_suffix, $query_name ); + + # This accounts for different naming of things based on our options + if ( $s->{exact} ) { + $m_type = 'term'; + $f_suffix = '.raw'; + $query_name = 'value'; + } + else { + $m_type = 'match'; + $f_suffix = ''; + $query_name = 'query'; + } + my $field = $s->{field} // "_all"; + my $m = { + $m_type => { + "$s->{field}$f_suffix" => { + $query_name => $s->{term}, + }, + }, + }; + push @match_parts, $m; + } + my $query; + if ( $options{and_or} && lc( $options{and_or} ) eq 'or' ) { + $query->{bool}{should} = \@match_parts; + } + else { + $query->{bool}{must} = \@match_parts; + } + return { query => $query }; +} + =head2 build_query my $simple_query = $builder->build_query("hello", %options) -- 2.1.4