(при выполнении взвешенной сортировки) Как распределить разные коэффициенты для полей на запрос? - PullRequest
0 голосов
/ 06 октября 2011

(я присоединяю и Solr, и SQL как теги, потому что я не знаю, что использовать в такой ситуации. Может быть, даже что-то еще)

Пример:

Веб приложение , которое должно сортировать задач на основе Время и Цена . У пользователя есть слайдер, который определяет, что важнее важно (время или цена).

Он должен выполнить взвешенную сортировку , где оценка результата зависит от Цена и Время , но должна быть возможность изменить коэффициенты , когда пользователь скользит по времени или соответственно к цене.

Пример 2:

Пользователь пытается найти правильные носки. Хотите знать, между тем, как зеленый и как долго они должны быть. Опять же, есть слайдер между этими двумя свойствами. Если на уровне ползунка 50%, пользователь заботится о том, насколько они зелёные, и насколько они длинны. Если ползунок ближе к зеленому краю, пользователя больше интересует, насколько зеленые носки, но они тоже хотят быть длинными.

Я не знаю, какое программное обеспечение использовать или как этого добиться.

Ответы [ 2 ]

0 голосов
/ 06 октября 2011

В Solr вы можете сделать запрос вроде:

time:[t]^[wt] price:[p]^[wp]

где [t] = запрошенное время, [p] = запрошенная цена, а [wt] и [wp] - веса; больший вес придает большее значение термину, к которому он применяется.

Это приведет к точному весу совпадений, но вы также можете вычислить непрерывные функции разницы между запрошенным значением и точным значением, используя FunctionQuery;

см. http://wiki.apache.org/solr/FunctionQuery для получения дополнительной информации об этом

0 голосов
/ 06 октября 2011

MS SQL SERVER ответ ...

DECLARE
  @min_time    DATETIME,
  @max_time    DATETIME,
  @min_price   MONEY,
  @max_price   MONEY
SELECT
  @min_time    = MIN(timestamp),
  @max_time    = MAX(timestamp),
  @min_price   = MIN(price),
  @max_price   = MAX(price)
FROM
  yourTable

SELECT
  *
FROM
  yourTable
ORDER BY
  (CAST(DATEDIFF(second, @min_time, timestamp) AS FLOAT) / CAST(DATEDIFF(second, @min_time, @max_time) AS FLOAT)) * @slider
  +
  (CAST(price - @min_price AS FLOAT) / CAST(@max_price - @min_price AS FLOAT)) * (1 - @slider)

-- Where te slider value is anything between 0 and 1

Чтобы заставить ваши настроения работать, я делаю один и тот же расчет времени и цены - я конвертирую их в значение от 0 до 1 (которое я назову positional weight).
- 0.0 = равно минимальному значению для этого поля
- 0.5 = точно на полпути между минимальным и максимальным значениями этого поля
- 1,0 = равно максимальному значению для этого поля

Затем я умножаю позиционный вес на значение ползунка (или значение 1) и складываю вместе два результата.

Когда ползунок на 0 или 1, это просто; один позиционный вес умножается на один, один позиционный вес умножается на ноль. Другими словами, один позиционный вес не изменяется, а один позиционный вес игнорируется.

Когда ползунок равен 0,5, половина каждого позиционного веса складывается вместе.


В случае, когда 99,999% значений расположены близко друг к другу и существует один экстремальный выброс, это может привести к тому, что это поле станет необычно доминирующим или наоборот. (Большинство позиционных весов очень близко к 0 или 1)

Таким образом, один из вариантов состоит в том, чтобы основывать позиционный вес только на порядке данных. Таким образом, в случае, когда многие значения близки, но с одним крайним выбросом; значение в середине списка по-прежнему получает 0,5, поскольку это позиционный вес. Короче говоря, важна его позиция в последовательности, а не ее фактическое значение.

DECLARE
  @count       FLOAT
SELECT
  @count       = CAST(COUNT(*) AS FLOAT)
FROM
  yourTable

WITH
  ordered_data
AS
(
SELECT
  ROW_NUMBER() OVER (ORDER BY timestamp) AS time_id,
  ROW_NUMBER() OVER (ORDER BY price)     AS price_id,
  *
FROM
  yourData
)
SELECT
  *
FROM
  ordered_data
ORDER BY
  (CAST(time_id AS FLOAT) / @count) * @slider
  +
  (CAST(price_id AS FLOAT) / @count) * (1 - @slider)


Что лучше, почему и т. Д. Начинает получать статистические данные и зависит именно от того, чего вы пытаетесь достичь. Может быть, вы могли бы взять среднее значение двух разных позиционных весов и использовать их? Надеюсь, это даст вам возможность поработать.


Оба ответа заставляют positional weight быть в процентах. Это потому, что ВРЕМЯ и ЦЕНА могут иметь совершенно разные масштабы. Делая их percantages (от 0 до 1) заставляет их быть одинакового масштаба. Возможно, вы захотите рассмотреть альтернативные механизмы для выбора подходящих шкал, и они могут отличаться для каждого поля.

Каждый ответ определяет позиционный вес относительно фиксированной точки: самого низкого пункта в списке. Вы можете выбрать другие контрольные точки, такие как СРЕДСТВО, РЕЖИМ или МЕДИАНА. При этом у вас будет диапазон позиционных весов (от -x до + y), причем x и y потенциально могут быть очень разными значениями. Затем вы можете изменить их вес (от -1 до +1). Это потребует масштабирования их вдоль кривой, и вам нужно будет решить, как определить эту кривую.

Каждый ответ вырабатывает «расстояние» от фиксированной контрольной точки от 0 до 1 или в предыдущем абзаце от -1 до +1. Это предполагает, что время и цена всегда одинаково важны. Но что, если вы выбрали только дорогие предметы, где позиционный вес всегда должен быть ближе к 1? Вам потребуется механизм для масштабирования по «всем возможным значениям», а не по «всем существующим значениям».

У вас есть большой выбор, и выбор правильного или неправильного зависит от функциональных требований, которые вы изложили. Я не верю, что есть универсальная Истина, которую можно найти. Возможно, вам нужно создать несколько примеров и решить, чего вы хотите достичь, а затем выяснить КАК?

...