Можно ли делать where in для поиска по json

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Можно ли делать where in для поиска по json

Сообщение Sereja3578 »

Всем привет. Есть вопрос, можно ли как-то написать типа такого в query builder

Код: Выделить всё

->andWhere(['@>', 'data', new JsonExpression(['data_chain' => ['slug' => "1"]])])
чтобы тут вместо 1 был массив и условие in? Какие есть варианты?

Вот целиком пример кода запроса

Код: Выделить всё

$successfulTransactions = $query->select(['bs.payment_id', 'guid', 'bs.data'])
            ->from('{{%billing_success}} bs')
            ->where(['between', 'tariffed_date', $startDate, $endDate])
            ->andWhere(['@>', 'data', new JsonExpression(['data_chain' => ['slug' => "1"]])])
            ->orderBy(['bs.id' => SORT_ASC])
            ->all();
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Можно ли делать where in для поиска по json

Сообщение unknownby »

Sereja3578 писал(а): 2021.05.31, 22:43 Всем привет. Есть вопрос, можно ли как-то написать типа такого в query builder

Код: Выделить всё

->andWhere(['@>', 'data', new JsonExpression(['data_chain' => ['slug' => "1"]])])
чтобы тут вместо 1 был массив и условие in? Какие есть варианты?

Вот целиком пример кода запроса

Код: Выделить всё

$successfulTransactions = $query->select(['bs.payment_id', 'guid', 'bs.data'])
            ->from('{{%billing_success}} bs')
            ->where(['between', 'tariffed_date', $startDate, $endDate])
            ->andWhere(['@>', 'data', new JsonExpression(['data_chain' => ['slug' => "1"]])])
            ->orderBy(['bs.id' => SORT_ASC])
            ->all();
Можно увидеть рабочий запрос в БД?
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Можно ли делать where in для поиска по json

Сообщение Sereja3578 »

Я сейчас сделал так через dao.

Код: Выделить всё

	    SELECT 
            bs.data->>'data_date' AS data_date,
            bs.payment_id, 
            guid,
            bs.data->>'data_msisdn' AS data_msisdn,
            bs.data->>'data_price' AS data_price,
            bs.data->>'data_cpa' AS data_cpa,
            bs.data->>'data_operator_group' AS data_operator_group
            FROM billing.public.billing_success bs
            WHERE tariffed_date BETWEEN :start_date AND :end_date
            AND data->>'data_product' in ('$productsSlugs')
            ORDER BY bs.id
Это в целом решает проблему, я даже смог сделать через query builder, добавив в andWhere условие строкой и оно работает. Выбрал первый вариант потому что в select нельзя добавлять ->>'name'
Последний раз редактировалось Sereja3578 2021.06.02, 18:50, всего редактировалось 1 раз.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Можно ли делать where in для поиска по json

Сообщение unknownby »

Sereja3578 писал(а): 2021.06.01, 23:59 Я сейчас сделал так через dao.
А тут что лежит $productsSlugs?

Код: Выделить всё

AND data->>'data_product' in ('$productsSlugs')
На сколько я знаю, если в значении будет одна цифра или массив, запрос составится верно.
Например:

Код: Выделить всё

MyModel::find()
->where(['id' => $ids])
->all();
Если $ids будет равен 1, выдаст запрос

Код: Выделить всё

SELECT * FROM table WHERE id = 1
Если в $ids будет массив идентификаторов [1,2,3,4], выдаст запрос такого рода

Код: Выделить всё

SELECT * FROM table WHERE id IN (1,2,3,4)
Под ваш запрос выходит такое условие

Код: Выделить всё

->andWhere(['data' => new JsonExpression($productsSlugs)])
Аватара пользователя
Sereja3578
Сообщения: 204
Зарегистрирован: 2016.09.21, 11:15
Контактная информация:

Re: Можно ли делать where in для поиска по json

Сообщение Sereja3578 »

В $productsSlugs лежит строка типа 'wqewq', 'wqeqweqw'

На счет

->andWhere(['data' => new JsonExpression($productsSlugs)])

Пока не понял суть.

Допустим в дата лежит jsonb

{
'a':'a',
'b': {
'c':'c',
'd':'d'
}
}

Нужно выбрать те данные у которых в этом джейсоне 'a' in ('a', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9') или где 'b':'c' in ('c', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9')

Я пробовал через JsonExpression, передавая туда путь в виде ['b' => ['c' => 'c']], так работает, но если делать ['b' => ['c' => ['c', 'c1']]], то ошибка, что типа неверный формат чего-то там.
Ответить