Как получить диапазоны фасетов в результатах Solr?

голоса
15

Предположим , что у меня есть поле под названием цена для документов в Solr и у меня есть это поле граненый. Я хочу , чтобы получить грани как диапазоны значений (например: 0-100, 100-500, 500-1000, и т.д.). Как это сделать?

Я могу указать диапазоны заранее, но я также хочу знать, можно ли вычислить диапазоны (скажем, 5 значений) автоматически на основе значений в документах?

Задан 29/08/2008 в 05:26
источник пользователем
На других языках...                            


4 ответов

голоса
14

Чтобы ответить на ваш первый вопрос, вы можете получить диапазоны фасетов с помощью поддержки родовой фаски запроса. Вот вам пример:

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

Что касается второго вопроса (автоматически предполагая фасеты диапазонов), который еще не реализован. Некоторые утверждают, что этот вид запроса будет лучше всего осуществлять на вашем приложении, а что позволить Solr «угадать» лучшие диапазоны фасеточных.

Вот некоторые дискуссии по этой теме:

Ответил 04/10/2008 d 16:04
источник пользователем

голоса
6

Я работал, как рассчитать разумные динамические аспекты для диапазонов цен продукта. Решение включает в себя некоторые предварительной обработки документов и некоторых пост-обработки результатов запроса, но она требует только один запрос к Solr, и должен работать даже на старой версии Solr как 1.4.

Округление цен до подачи

Во- первых, перед отправкой документа, сгонять на цену до ближайшей «хорошей границей круглый фасет» и сохранить его в поле «rounded_price». Пользователи , как их грани выглядеть «250-500» не «247-483», и округление также означает , что вы получите обратно сотни ценовых граней не миллионы из них. С некоторым усилием следующий код может быть обобщена округлить красиво в любой ценовой шкале:

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

Допустимые цены идут 1,2,3, ..., 24,25,30,35, ..., 95100110, ..., 240.250.275.300.325, ..., 975,1000 и так далее.

Получить все аспекты по закругленным ценам

Во- вторых, при подаче запроса, запрос все аспекты по закругленными цен , отсортированный по цене: facet.field=rounded_price. Благодаря скругления, вы получите максимум несколько сотен граней назад.

Объединить смежные грани в большие грани

В- третьих, после того, как у вас есть результаты, пользователь хочет видеть только 3 до 7 граней, а не сотни граней. Таким образом, объединить смежные грани в нескольких больших грани ( так называемых «сегменты») пытается получить примерно равное количество документов в каждом сегменте. Следующие несколько сложнее коды делают это, возвращая кортежи (начало, конец, количество) подходят для выполнения запросов диапазона. Подсчеты Возвращенные будут правильные , предоставленные цены были округлены до ближайшей границы:

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

Фильтр по выбранной фаске

В-четвертых, предположим, что ( "250", "500", 38) был одним из полученных сегментов. Если пользователь выбирает «$ 250 до $ 500» в качестве фильтра, просто сделать запрос фильтраfq=price:[250 TO 500]

Ответил 04/07/2012 d 14:14
источник пользователем

голоса
4

Там также может быть лучше Solr-конкретный ответа, но я работаю с прямым Lucene, и так как вы не получаете много тяги я возьму удар. Там, я бы создать заселить Filterс FilteredQueryоберточной оригинал Query. Тогда я бы получить FieldCacheв поле интересов. Перечислять хиты в BitSet фильтра, и для каждого удара, вы получаете значение поля из кэша поля, и добавить его в SortedSet. Когда у вас есть все хиты, разделить размер набора в число диапазонов , которые вы хотите (пять семь хороший номер в соответствии с пользовательским интерфейсом , ребята), и вместо того , однозначное ограничение, ваши аспекты будут быть диапазон запросы с нижними и верхними пределами каждого из этих подмножеств.

Я бы рекомендовал использовать некоторую специальный случай логику для небольшого числа значений; Очевидно, если у вас есть только четыре различного значения, это не имеет смысла, чтобы попытаться сделать уточнения 5 диапазона из них. Ниже определенного порогового значения (скажем, 3 * Идеальное количество диапазонов), вы просто показать грани, как правило, а не диапазоны.

Ответил 29/08/2008 d 06:53
источник пользователем

голоса
3

Вы можете использовать SOLR диапазоны фасетов

http://wiki.apache.org/solr/SimpleFacetParameters#Facet_by_Range

Ответил 15/05/2012 d 11:42
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more