Reputation: 923
I want to use elastic search to search through a large address database, and to make it like some other applications I start with the postcode first which is great to narrow down on the rest of the search query.
So with Search::Elasticsearch
I do
my $scroll = $e->scroll_helper(index => 'pdb', search_type => 'scan', size => 100,
body => {
query => {
bool => {
filter => [
{match => { pcode => $postcode }},
],
should => [
{match => { address => $keyword }},
{match => { name => $keyword }},
],
}
}
}
);
However that just spits out everything for $postcode
and regardless of what $keyword
is the result set is not further reduced.
I need to have $postcode
as a mandatory condition but also separately and in addition the other two fields to also be taken into account as a full text search.
How should I do this (Im looking at the docs and might be interpreting json->perl hashrefs wrong so any suggestions welcome)
For a hypothetical example:
User enters NW1 4AQ
, The above query will immediately return, say, Albany Street and Portland Street, if the user queries Portland
and that postcode, instead of getting both those results, I expect only Portland Street to be the result. Right now with the above It just keeps returning both entries.
Upvotes: 9
Views: 1623
Reputation: 923
Following common sense I found that the following does what I want for the bool
segment:
bool => {
must => [
{match => { pcode => $postcode }},
],
should => [
{match => { address => $keyword }},
{match => { name => $keyword }},
],
minimum_should_match => 1,
}
Having minimum_should_match
as 1 (which is a counter rather than true/false), feels like it's inserting an OR
in those should
s
Upvotes: 4
Reputation: 1082
Elastic doc says:
"By default, none of the should clauses are required to match, with one exception: if there are no must clauses, then at least one should clause must match. Just as we can control the precision of the match query, we can control how many should clauses need to match by using the
minimum_should_match
parameter, either as an absolute number or as a percentage"
So the way to do it is through minimum_should_match
. Just as you did. What you did means that either address or name must be matched.
Upvotes: 2