View | Details | Raw Unified | Return to bug 24902
Collapse All | Expand All

(-)a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm (-10 / +16 lines)
Lines 853-868 sub _join_queries { Link Here
853
      map { s/^mc-//r } grep { defined($_) && $_ ne '' && $_ =~ /^mc-/ } @parts;
853
      map { s/^mc-//r } grep { defined($_) && $_ ne '' && $_ =~ /^mc-/ } @parts;
854
    return () unless @norm_parts + @mc_parts;
854
    return () unless @norm_parts + @mc_parts;
855
    return ( @norm_parts, @mc_parts )[0] if @norm_parts + @mc_parts == 1;
855
    return ( @norm_parts, @mc_parts )[0] if @norm_parts + @mc_parts == 1;
856
    my $grouped_mc =
856
857
      @mc_parts ? '(' . ( join ' OR ', map { "($_)" } @mc_parts ) . ')' : ();
857
    # Group limits by field, so they can be OR'ed together
858
858
    my %mc_limits;
859
    # Handy trick: $x || () inside a join means that if $x ends up as an
859
    foreach my $mc_part (@mc_parts) {
860
    # empty string, it gets replaced with (), which makes join ignore it.
860
        my ($field, $value) = split /:/, $mc_part, 2;
861
    # (bad effect: this'll also happen to '0', this hopefully doesn't matter
861
        $mc_limits{$field} //= [];
862
    # in this case.)
862
        push @{ $mc_limits{$field} }, $value;
863
    join( ' AND ',
863
    }
864
        join( ' AND ', map { "($_)" } @norm_parts ) || (),
864
865
        $grouped_mc || () );
865
    @mc_parts = map {
866
        sprintf('%s:(%s)', $_, join (' OR ', @{ $mc_limits{$_} }));
867
    } sort keys %mc_limits;
868
869
    @norm_parts = map { "($_)" } @norm_parts;
870
871
    return join( ' AND ', @norm_parts, @mc_parts);
866
}
872
}
867
873
868
=head2 _make_phrases
874
=head2 _make_phrases
(-)a/t/Koha/SearchEngine/ElasticSearch/QueryBuilder.t (-2 / +30 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 5;
20
use Test::More tests => 6;
21
use t::lib::Mocks;
21
use t::lib::Mocks;
22
22
23
use_ok('Koha::SearchEngine::Elasticsearch::QueryBuilder');
23
use_ok('Koha::SearchEngine::Elasticsearch::QueryBuilder');
Lines 223-226 subtest '_clean_search_term() tests' => sub { Link Here
223
    is($res, 'test  another part', 'unbalanced curly brackets replaced correctly');
223
    is($res, 'test  another part', 'unbalanced curly brackets replaced correctly');
224
};
224
};
225
225
226
subtest '_join_queries' => sub {
227
    plan tests => 6;
228
229
    my $params = {
230
        index => $Koha::SearchEngine::Elasticsearch::BIBLIOS_INDEX,
231
    };
232
    my $qb = Koha::SearchEngine::Elasticsearch::QueryBuilder->new($params);
233
234
    my $query;
235
236
    $query = $qb->_join_queries('foo');
237
    is($query, 'foo', 'should work with a single param');
238
239
    $query = $qb->_join_queries(undef, '', 'foo', '', undef);
240
    is($query, 'foo', 'should ignore undef or empty queries');
241
242
    $query = $qb->_join_queries('foo', 'bar');
243
    is($query, '(foo) AND (bar)', 'should join queries with an AND');
244
245
    $query = $qb->_join_queries('homebranch:foo', 'onloan:false');
246
    is($query, '(homebranch:foo) AND (onloan:false)', 'should also work when field is specified');
247
248
    $query = $qb->_join_queries('homebranch:foo', 'mc-itype:BOOK', 'mc-itype:EBOOK');
249
    is($query, '(homebranch:foo) AND itype:(BOOK OR EBOOK)', 'should join with OR when using an "mc-" field');
250
251
    $query = $qb->_join_queries('homebranch:foo', 'mc-itype:BOOK', 'mc-itype:EBOOK', 'mc-location:SHELF');
252
    is($query, '(homebranch:foo) AND itype:(BOOK OR EBOOK) AND location:(SHELF)', 'should join "mc-" parts with AND if not the same field');
253
};
254
226
1;
255
1;
227
- 

Return to bug 24902