#php #laravel #postgresql #data-warehouse
#php #laravel #postgresql #хранилище данных
Вопрос:
Итак, я бьюсь головой уже несколько дней… Я должен каким-то образом найти «похожий» заказ на основе элементов начального заказа SKU и сгруппировать их в партии по 20 слотов * 40 кг в каждом слоте, так что в общей сложности 800 кг макс.
У меня есть две таблицы orders и order_items. Таблица заказов содержит идентификатор и идентификатор магазина и некоторые временные метки. Таблица элементов заказа содержит order_id, артикул, количество и объем / вес.
Я использую Laravel 8. *, PHP 7.4 и Postgres
Что я уже пробовал:
Получение начального заказа, который является самым старым в пуле заказов, найденных конкретной группой пакетов, которая выглядит следующим образом
//The batch group query
if (!empty($batchGroup->group['carriers'])) {
$this->whereIn('carrier', $batchGroup->group['carriers']);
}
if (!empty($batchGroup->group['methods'])) {
$this->whereIn('method', $batchGroup->group['methods']);
}
if (!empty($batchGroup->group['countries'])) {
foreach ($batchGroup->group['countries'] as $k => $country) {
if ($k === 0) {
$this->where('country', '=', $country);
} else {
$this->where('country', '=', $country, 'or');
}
}
}
После этого я получаю артикулы этого заказа, делая это:
$seedItemsSku = $seedOrder->items->pluck('sku')->toArray();
//Here i have array with SKUS: [102312, 150021, 125125] etc...
Здесь начинается самое интересное…
Я создал функцию в построителе запросов, которая должна возвращать все совпадающие заказы
public function similar(Order $seedOrder, BatchGroup $batchGroup, array $exceptOrders = []): self
{
$skus = $seedOrder->items->pluck('sku')->toArray();
$query = $this;
if (!empty($exceptOrders)) {
$query->whereNotIn('id', $exceptOrders);
}
return $this->whereHas('items', function (OrderItemQueryBuilder $builder) use ($skus) {
$builder->whereIn('sku', $skus);
})
->whereNull('batch_id')
->where('total_weight', '<=', 200);
}
Проблема с приведенной выше функцией заключается в том, что она получает результат, который со смешанными артикулами не СОВСЕМ соответствует начальным артикулам. Кроме того, это очень медленно.
Я ищу способ / совет, как я могу достичь этого результата.
Вот сценарий: магазин получил 5 тыс. заказов за ночь. Они должны быть упакованы на следующий день. Система получает самый старый заказ, берет артикулы и начинает искать похожие заказы, 100% совпадение артикулов будет идеальным. Но если у нас есть заказ с этим артикулом и еще один, которого нет в начальном заказе, у нас снова совпадение. Цель состоит в том, чтобы добиться максимальной эффективности партии и избежать обхода большого склада для 5 заказов. Кроме того, товары на складе имеют местоположение, по которому я буду сортировать конечный результат по ячейкам партии.
IMO, это странная логика, но именно так работает клиент, и сборщики / упаковщики привыкли.
ОБНОВЛЕНИЕ: это запрос, который должен находить похожие заказы.
SELECT
id, country, total_items, total_weight, batch_id
FROM
"orders"
WHERE
EXISTS (
SELECT
*
FROM
"order_items"
WHERE
"orders"."id" = "order_items"."order_id"
AND "sku" in('104026')
AND "order_items"."deleted_at" IS NULL)
AND "country" = 'Germany'
AND "orders"."deleted_at" IS NULL
Это результат:
Комментарии:
1. Я не понимаю, как
whereIn
создается нечеткое совпадение по артикулам. Это строгое сравнение в том смысле, что значениеsku
должно существовать в массиве$skus
.2. Он соответствует хотя бы одному, но возвращает результат с другим артикулом в порядке, а не только с выбранными