2008-08-29 25 views
15

Solr belgedeki belgeler için fiyat isimli bir alanım olduğunu ve bu alana sahip olduğumu varsayalım. Yüzleri değerler aralığı olarak almak istiyorum (örneğin: 0-100, 100-500, 500-1000, vb.). Nasıl yapılır?Solr sonuçlarında faset aralıkları nasıl elde edilir?

Aralıkları önceden belirtebilirim, ancak aynı zamanda, belgelerindeki değerlere göre aralıkların (5 değer için) otomatik olarak hesaplanmasının mümkün olup olmadığını bilmek isterim?

cevap

4

Daha iyi Solr'a özgü bir cevap olabilir, ancak ben Lucene ile çalışıyorum ve fazla çekiş yapamadığınız için bir bıçak alacağım. Orada, orijinal Query'u saran FilteredQuery ile bir Filter doldurun. Sonra ilgi alanı için bir FieldCache alırdım. Filtrenin bitsetindeki isabetleri numaralandırır ve her isabet için alanın önbelleğinden alan değerini alır ve bir SortedSet'e eklersiniz. Tüm isabetlere sahip olduğunuzda, setin boyutunu istediğiniz aralık sayısına bölün (beş ile yedi arası, kullanıcı arabirimine göre iyi bir sayıdır) ve tek değerli bir kısıtlama yerine fasetleriniz Bu alt kümelerin her birinin alt ve üst sınırlarıyla bir aralık sorgulaması yapın.

Az sayıda değer için bazı özel durum mantığını kullanmanızı öneririm; Açıkçası, sadece dört ayrı değeriniz varsa, bunlardan 5 dizi iyileştirme yapmayı denemek mantıklı değildir. Belirli bir eşiğin altında (3 * ideal aralığınız), menzilleri normalden ziyade normal olarak gösterirsiniz.

14

İlk sorunuzu yanıtlamak için, genel faset sorgu desteğini kullanarak faset aralıkları alabilirsiniz. Here 'ın bir örnek: İkinci soruya gelince

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

(otomatik faset aralıkları düşündüren), yani henüz uygulanmadı değil. Bazıları, bu tür sorgulamanın, uygulamanıza en iyi şekilde uygulanacağını, bunun yerine Solr'ın en iyi faset aralıklarını "tahmin etmesini" öneriyor. İşte

konu hakkında bazı tartışmalar şunlardır:

+1

Partiye altı yıl geçebilir, ancak bağlantılar artık işe yaramaz. – Bucket

+1

@DesertIvy Lütfen, onları archive.org veya başka bir yere bakın ve cevabı düzenleyin. –

+0

Vay, bunun olduğunu bile bilmiyordum. Harika bir araç! – Bucket

6

Ürün fiyat aralıkları için hassas dinamik yönlerin nasıl hesaplanacağını öğrendim. Çözüm, bazı belgelerin önceden işlenmesini ve bazı sorgulama işlemlerinin sonradan işlenmesini içerir, ancak Solr'a yalnızca bir sorgu gerektirir ve hatta Solr'ın 1,4 gibi eski sürümü üzerinde çalışmalıdır. gönderilmeden önce

Yuvarlak yukarı fiyatları

Birincisi, belge göndermeden önce, bir "rounded_price" alanında yakın "güzel yuvarlak faset sınır" için fiyat ve saklayın yuvarlak. Kullanıcıların yüzleri gibi "250-500" gibi görünmesi "247-483" değil, yuvarlama da yüz milyonlarca yüzlerce fiyat yüzüne sahip olmanız anlamına geliyor., ..., 24,25,30,35, ..., 95.100.110

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; 
    } 

İzin verilen fiyatlar 1,2,3 go: Bazı çaba ile aşağıdaki kod herhangi bir fiyat ölçeğinde güzel yuvarlamak jeneralize olabilir ..., 240,250,275,300,325, ... 975,1000 vb. facet.field=rounded_price:

yuvarlak fiyatlara

İkincisi, sorgu gönderirken, fiyat sıralaması yuvarlak fiyatlara tüm yönleriyle talep üzerindeki tüm yönleriyle alın. Yuvarlama sayesinde, birkaç yüz yüze geri döneceksiniz.

sonuçları aldıktan sonra, kullanıcı sadece 3 ila 7 yönleriyle değil, yönleri yüzlerce bkz istiyor

Üçüncü büyük yönlerini içine bitişik yönlerini birleştirin. Böylece, bitişik yüzleri, her segmentte kabaca eşit sayıda belge almaya çalışan birkaç büyük yüze ("segmentler" olarak adlandırılır) birleştirir. Aşağıdaki oldukça karmaşık kod, bunu, aralık sorguları gerçekleştirmek için uygun (başlangıç, bitiş, sayım) döndürme işlemlerini döndürür. Doğru sağladığı fiyatları olacak döndürülen sayıları en yakın sınıra kadar yuvarlanmıştır edildi:

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; 
    } 

Filtre sonuçlarını seçilen faset

Dördüncü olarak, varsayalım tarafından ("250", "500", 38) idi Ortaya çıkan segmentlerden biri. Kullanıcı bir filtre olarak "250 $ ila 500 $" seçerse, sadece bir filtre sorgusu yapın fq=price:[250 TO 500]

İlgili konular