Сортировка элементов по значению, рассчитанному на ходу (не сохраняется) - PullRequest
0 голосов
/ 29 января 2019

В моем проекте я использую Laravel 5.5 с Eloquent и Scout драйверами для создания своего рода конечной точки API поисковой системы.

В моем сценарии у меня есть таблица SQL items, котораяимеет свойство price_factor.Таблица также хранится в индексе Elasticsearch.

С этим значением и номером пользователя, связанного с этим элементом, я могу рассчитать правильную цену объекта.

AnПростой пример: элемент с id: 1 имеет price_factor: 2 и связан с 5 users.Конечно, правильная цена предмета - 2 * 5 = 10.

Теперь я должен запросить все результаты и использовать where conditions, сортируя их по этому вычисленному свойству, и возвращать разбитые на страницы результаты.

Например: получить все товары с ценой от 5 до 10, отсортировать их по price и разбить на страницы по 10 элементов на странице.

В Eloquent я напишу:

// Set filters to be applied
$filters = [
    ['price', '>', 5],
    ['price', '<', 10],
];
// Sort by "update_at", or "price"
$sort = "price";
// Order by "ASC" mode
$order = "ASC";
// Number of rows per page
$rows = 10;

// Get items
$result = Item::orderBy(
    $sort,
    $order
// Get related user with item record, where has...
)->with(['users'])->whereHas(
    // Take users related models
    'users',
    // Take the model related ("user") and use filters
    function($relation_model) use ($filters) {
        // Apply where condition with filters
        $relation_model->where($filters);
    }
// Paginate for the numbers of row requested
)->paginate($rows);

Как это сделать, если price не является свойством таблицы items?

Стоит ли хранить цену внутри таблицы и обновлять ее при каждом добавлении нового отношения пользователя?(или каждое удаленное отношение тоже).Это правильный подход?

Я думал о веб-сайте, подобном eBay, или о другом аукционе в реальном времени, с похожей ситуацией моего: как вы думаете, они решили?

Спасибозаранее.

1 Ответ

0 голосов
/ 29 января 2019

Предполагая, что у вас есть таблица user_items, которая отслеживает элементы, принадлежащие пользователю, я думаю, что-то вроде этого может сработать:

$result = Item::selectRaw('items.*, price_factor * (SELECT COUNT(id) FROM user_items WHERE user_items.item_id = items.id) AS price')
    ->with(['users'])
    ->havingRaw('price > ? AND price < ?', [5, 10])
    ->orderBy('price', 'asc')
    ->paginate($rows);

Вы можете рассчитать цену на лету и присвоить ей псевдоним.,Наконец, вы можете применить к нему havingRaw предложение, которое проверит, находится ли цена между нужным диапазоном.Вот рабочий пример этого в действии.

Возможно, есть лучшие способы сделать это.Мне тоже интересно узнать :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...