Creazione di un filtro facet utilizzando Elasticsearch

0

Mi è stato chiesto di creare una funzionalità di filtro per l'applicazione di e-commerce scritta in PHP. Poiché l'app utilizza il database MySQL, ho deciso di utilizzare Elasticsearch con Logstash e Kibana.

Ora questa parte è chiara, utilizzando Logstash per trasferire i dati da MySQL a Elasticsearch e quindi utilizzare il client php Elasticsearch per accedervi.

Ciò che sto pensando in questo momento è se dovessi ottenere gli ID prodotto in base ai risultati del filtro sfaccettatura (aggregazioni ES) e caricarli dal database MySQL, creare gli oggetti in PHP e recuperare i risultati ... o in qualche altro modo sarebbe buono?

Inoltre, penso che la sfida più grande per me siano le combinazioni di aggregazione, e. g. link dove puoi vedere che spuntando un altro attributo mostrerà altri 5 prodotti ecc.

Come realizzarlo? Dovrei semplicemente "pre-caricare" tutte le altre possibili aggregazioni per il prossimo passo? Perché sembra così sbagliato.

    
posta falnyr 03.06.2016 - 12:03
fonte

1 risposta

2

Non è chiaro cosa esattamente chiedi. Non possiamo scrivere un tutorial su Elasticsearch qui.

Come panoramica generale:

Dovresti avere un indice ES che contenga tutte le informazioni che potresti voler cercare / aggregare / sfaccettare e anche tutte o la maggior parte delle informazioni che desideri visualizzare.

La tua ricerca ha due parti fondamentali:

La ricerca stessa che restituisce i prodotti. Questa è una combinazione di ricerca del testo e ricerca per termini (per attributi come dimensione ecc.)

Le aggregazioni su facet che restituiscono le opzioni del prodotto che vengono "lasciate" dopo aver applicato la ricerca. Questo è ciò che visualizzi come filtri.

Quindi per il tuo esempio, l'unica cosa già selezionata è l''attributo della categoria'. Questo limita i risultati della ricerca. Di conseguenza, le tue sfaccettature restituiranno solo attributi correlati a "abiti" come le dimensioni, il colore ecc.

Fai attenzione che quegli attributi di filtro possono essere o un risultato diretto della ricerca (solo 'ciò che è rimasto') o possono essere ulteriormente filtrati dal codice (non vogliamo mostrare l'opzione X per l'abbigliamento. (Oppure puoi fare certo che durante l'inserimento del prodotto è già impossibile aggiungere determinati attributi ai prodotti in quelle categorie).

Dopo aver ottenuto i risultati è possibile caricare ulteriori informazioni da MySQL, se necessario. Ma sarà più performante e più facile da gestire per molti casi se memorizzi tutte le informazioni in ES, ove possibile.

Ok, qualche codice pratico (ridotto il più possibile, così evidenziato, ecc.):

Il generatore di query di livello superiore:

  query: {filtered: {query: Elastic::Element.match(text)}},
  aggs: Elastic::Aggs.new(self),
  post_filter: Elastic::Element.post_filter(filters),

Questo è ciò che abbiamo inviato a ES. La parte della query, l'aggs (abbiamo bisogno di ottenere le categorie / attributi ...) e un filtro post. (evidenzia anche, ordina e impaginazione, ma ignoriamo questo qui). Inoltre è una query di ricerca, non una query di conteggio (quindi recuperiamo gli elementi, non solo i conteggi aggregati)

La query viene creata con un metodo e avrà il seguente aspetto:

{ multi_match: {
  query:                'some text the user entered (or empty),
  type:                 'best_fields',
  operator:             'and',
  minimum_should_match: '3<75%',
  fields:               ['search_id^10', 'ean^10', 'title^1', 'text', 'text_*'],
  tie_breaker:          0.3
      }
    }

Questa è fondamentalmente una ricerca di testo qui. Se l'utente non ha inserito un termine di ricerca, viene sostituito da:

{ match_all: {} }

Il post_filter è dove vengono gli attributi in:

{ bool: 
  { must: [
    {
      terms: {
        'color' => ['black', 'purple'],
        execution: 'bool',
      }
    },
    {
      terms: {
        'category' => ['dresses'],
        execution: 'bool',
      }
    }
  ]
} }

Quindi in pratica il filtro bool è dove aggiungi questa funzionalità. (Il filtro dei termini è solo uno, benché quello che userai la maggior parte del tempo).

Quindi questo è fondamentalmente come lo facciamo. La sintassi un po 'strana è perché copio / incollo questo codice da un vero codice Ruby (useresti JSON che sembra sostanzialmente lo stesso per quanto riguarda la strutturazione).

Utilizzerai anche tonnellate di funzioni di supporto, ad esempio l'intero filtro post inizia come una matrice come [{'color' => ['black', 'purple']}, 'category' => ['dresses']] che a sua volta viene generata dall'input del modulo utente.

Quindi viene convogliato attraverso una funzione che genera i termini (La chiamata a Elastic::Element.post_filter(filters) sul primo livello).

    
risposta data 03.06.2016 - 12:27
fonte

Leggi altre domande sui tag