2008-08-29 10 views
15

Si supponga di avere un campo chiamato prezzo per i documenti in Solr e ho il campo sfaccettato. Voglio ottenere le sfaccettature come intervalli di valori (ad esempio: 0-100, 100-500, 500-1000, ecc.). Come farlo?Come ottenere intervalli di facet nei risultati solr?

Posso specificare anticipatamente gli intervalli, ma voglio anche sapere se è possibile calcolare automaticamente gli intervalli (ad esempio per 5 valori) in base ai valori nei documenti?

risposta

4

Potrebbe esserci una risposta specifica per Solr, ma io lavoro con Lucene dritto, e dato che non si ottiene molta trazione, mi prendo una pugnalata. Lì, vorrei creare un popolare uno Filter con un FilteredQuery avvolgendo l'originale Query. Quindi ricevo un FieldCache per il campo di interesse. Enumera gli hit nel set di bit del filtro e, per ogni hit, ottieni il valore del campo dalla cache dei campi e lo aggiungi a un SortedSet. Quando hai tutti i successi, dividi la dimensione del set nel numero di intervalli che vuoi (cinque a sette è un buon numero in base all'interfaccia utente), e piuttosto che un vincolo a valore singolo, le tue sfaccettature essere una query di intervallo con i limiti inferiore e superiore di ciascuno di questi sottoinsiemi.

Si consiglia di utilizzare una logica di caso speciale per un numero ridotto di valori; ovviamente, se si hanno solo quattro valori distinti, non ha senso cercare di fare 5 raffinamenti di gamma su di essi. Al di sotto di una certa soglia (diciamo 3 * il numero ideale di intervalli), è sufficiente mostrare le sfaccettature normalmente piuttosto che le distanze.

14

Per rispondere alla prima domanda, è possibile ottenere intervalli di facet utilizzando il supporto di query di facet generico. s' Here un esempio:

http://localhost:8983/solr/select?q=video&rows=0&facet=true&facet.query=price:[*+TO+500]&facet.query=price:[500+TO+*] 

Per quanto riguarda la seconda domanda (che suggerisce automaticamente gli intervalli sfaccettatura), che non è ancora implementata. Alcuni sostengono che questo tipo di interrogazione sarebbe meglio implementato sulla vostra applicazione piuttosto che lasciare che Solr "indovini" i migliori intervalli di faccette.

Ecco alcune discussioni sul tema:

+1

Potrebbe essere sei anni di ritardo alla festa, ma i collegamenti non funzionano più. – Bucket

+1

@DesertIvy In ogni caso, cercali su archive.org o altrove e modifica la risposta. –

+0

Wow, non sapevo nemmeno che esistesse. Ottimo strumento! – Bucket

6

Ho elaborato come calcolare le sfaccettature dinamiche sensibili per le fasce di prezzo dei prodotti. La soluzione prevede alcuni pre-elaborazione dei documenti e alcuni post-elaborazione dei risultati dell'interrogazione, ma richiede solo una query per Solr e dovrebbe funzionare anche su una vecchia versione di Solr come 1.4.

rotonde in alto i prezzi prima presentazione

In primo luogo, prima di inviare il documento, Round Up il prezzo al più vicino "bella confine sfaccettatura rotonda" e conservarlo in un campo "rounded_price". Agli utenti piacciono le faccette per apparire come "250-500" non "247-483" e arrotondare significa anche che si ottengono centinaia di sfaccettature di prezzo, non milioni di esse.Con qualche sforzo il seguente codice può essere generalizzato per arrotondare bene a qualsiasi scala di prezzo:

public static decimal RoundPrice(decimal price) 
    { 
     if (price < 25) 
      return Math.Ceiling(price); 
     else if (price < 100) 
      return Math.Ceiling(price/5) * 5; 
     else if (price < 250) 
      return Math.Ceiling(price/10) * 10; 
     else if (price < 1000) 
      return Math.Ceiling(price/25) * 25; 
     else if (price < 2500) 
      return Math.Ceiling(price/100) * 100; 
     else if (price < 10000) 
      return Math.Ceiling(price/250) * 250; 
     else if (price < 25000) 
      return Math.Ceiling(price/1000) * 1000; 
     else if (price < 100000) 
      return Math.Ceiling(price/2500) * 2500; 
     else 
      return Math.Ceiling(price/5000) * 5000; 
    } 

prezzi ammissibili vanno 1,2,3, ..., 24,25,30,35, ..., 95.100.110 , ..., 240,250,275,300,325, ..., 975,1000 e così via.

ottenere tutti gli aspetti sui prezzi arrotondati

In secondo luogo, al momento della presentazione della domanda, richiedere tutte le sfaccettature sui prezzi arrotondati scelte per prezzo: facet.field=rounded_price. Grazie all'arrotondamento, otterrai al massimo alcune centinaia di faccette.

Combina sfaccettature adiacenti in sfaccettature più grandi

In terzo luogo, dopo avere i risultati, l'utente vuole visualizzare solo da 3 a 7 sfaccettature, non centinaia di sfaccettature. Quindi, combina le faccette adiacenti in alcuni grandi lati (detti "segmenti") cercando di ottenere un numero approssimativamente uguale di documenti in ciascun segmento. Il seguente codice piuttosto complicato fa questo, restituendo tuple di (inizio, fine, conteggio) adatte per eseguire query di intervallo. I conteggi restituiti saranno corretti prezzi forniti sono stati stati arrotondati fino al limite più vicino:

public static List<Tuple<string, string, int>> CombinePriceFacets(int nSegments, ICollection<KeyValuePair<string, int>> prices) 
    { 
     var ranges = new List<Tuple<string, string, int>>(); 
     int productCount = prices.Sum(p => p.Value); 
     int productsRemaining = productCount; 
     if (nSegments < 2) 
      return ranges; 
     int segmentSize = productCount/nSegments; 
     string start = "*"; 
     string end = "0"; 
     int count = 0; 
     int totalCount = 0; 
     int segmentIdx = 1; 
     foreach (KeyValuePair<string, int> price in prices) 
     { 
      end = price.Key; 
      count += price.Value; 
      totalCount += price.Value; 
      productsRemaining -= price.Value; 
      if (totalCount >= segmentSize * segmentIdx) 
      { 
       ranges.Add(new Tuple<string, string, int>(start, end, count)); 
       start = end; 
       count = 0; 
       segmentIdx += 1; 
      } 
      if (segmentIdx == nSegments) 
      { 
       ranges.Add(new Tuple<string, string, int>(start, "*", count + productsRemaining)); 
       break; 
      } 
     } 
     return ranges; 
    } 

Filtra i risultati tramite sfaccettatura

In quarto luogo, supponiamo selezionato ("250", "500", 38) era uno dei segmenti risultanti. Se l'utente seleziona "$ 250 a $ 500" come filtro, fai semplicemente una query di filtro fq=price:[250 TO 500]

Problemi correlati