2016-06-14 47 views
8

Desidero utilizzare la ricerca elastica per cercare un database di indirizzi di grandi dimensioni e per renderlo simile ad altre applicazioni, comincio innanzitutto con il codice postale, che è ottimo per restringere il resto di la query di ricerca.Ricerca elastica: utilizzare il filtro e la query bool

Quindi, con Search::Elasticsearch

faccio

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 }}, 
       ], 
      } 
     } 
    } 
); 

Tuttavia che appena sputa fuori tutto per $postcode e indipendentemente da ciò che $keyword è il set di risultati non è ulteriormente ridotto.

Ho bisogno di avere $postcode come condizione obbligatoria ma anche separatamente e in aggiunta gli altri due campi da prendere in considerazione come ricerca di testo completo. Come devo fare questo (sto guardando la documentazione e potrebbe essere l'interpretazione json-> perl hashrefs sbagliato così eventuali suggerimenti di benvenuto)

Per un esempio ipotetico: entra utente NW1 4AQ, La query sopra ritorna immediatamente, per esempio, Albany Street e Portland Street, se l'utente interroga il codice postale Portlande, invece di ottenere entrambi questi risultati, mi aspetto che solo Portland Street sia il risultato. In questo momento con quanto sopra, continua a restituire entrambe le voci.

+0

e 'possibile creare un [esempio minimo, completo e verificabile] (http:... // StackOverflow .com/help/mcve)? –

+0

Aggiunge un ipotetico esempio ipotetico. – Recct

risposta

2

Dopo il buon senso ho trovato che la seguente fa quello che voglio per il bool segmento:

bool => { 
      must => [ 
       {match => { pcode => $postcode }}, 
      ], 
      should => [ 
       {match => { address => $keyword }}, 
       {match => { name => $keyword }}, 
      ], 
       minimum_should_match => 1, 
     } 

Avere minimum_should_match come 1 (che è un contatore invece di vero/falso), si sente come se fosse l'inserimento di un OR in quelli should s

1

doc elastico dice:

"per impostazione predefinita, nessuna delle s le clausole hould devono corrispondere a, con un'eccezione: se non ci sono clausole, allora almeno una clausola deve corrispondere. Così come siamo in grado di controllare la precisione della query partita, siamo in grado di controllare il numero di clausole devono necessariamente corrispondere utilizzando il parametro minimum_should_match, sia come numero assoluto o in percentuale"

Quindi il modo per farlo è attraverso minimum_should_match Proprio come hai fatto quello che hai fatto significa che o indirizzo o nome deve essere abbinato