postgres активной записи проверяют, содержит ли массив jsonb x или y - PullRequest
0 голосов
/ 28 сентября 2019

У меня есть таблица со столбцом jsonb, который имеет вложенный массив json.Я хотел бы найти все записи, где вложенный массив содержит хотя бы одно из значений.

Например, в моей модели Person есть столбец jsonb с именем Preferences.Внутри настроек jsonb есть несколько ключей, одним из которых является массив:

Person.first.preferences = {"diet" => {"foods" => ["apples", "oranges", "bananas"]}}

Я хотел бы создать запрос, который возвращает всех людей, чьи настройки -> диета -> продукты включают 'яблоки ИЛИ «mangos» (например).

В настоящее время я могу получить результаты с 1 вводом (т. е. «яблоки») следующим образом:

Person.where('preferences @> ?', {'diet' => {'foods' => ['apples']}}.to_json)

И несколькими входами, есливсе они существуют в массиве.Поэтому, если я передам «яблоки» и «апельсины», результат будет возвращен, потому что запись включает ОБА яблоки и апельсины.

Person.where('preferences @> ?', {'diet' => {'foods' => ['apples', 'oranges']}}.to_json)

Есть ли способ передать несколько переменных (т. Е. ['Яблоки',' mangos ']) и проверьте, содержит ли вложенный массив jsonb яблоки ИЛИ mangos, но не обязательно оба?

В следующем запросе нет результатов, потому что в пищевых предпочтениях моего персонажа нет mangos, хотяони включают яблоки.

Person.where('preferences @> ?', {'diet' => {'foods' => ['apples', 'mangos']}}.to_json)

Использование Rails 5.2 и Postgresql 10

Спасибо!

1 Ответ

3 голосов
/ 28 сентября 2019

Первое, что нужно сделать, это добраться до массива с помощью -> или #>, а затем вы можете использовать оператор ?| , чтобы проверить, перекрывает ли массив то, что вы ищете,Примерно так: SQL:

preferences->'diet'->'foods' ?| array['apples', 'mangos']

или с ActiveRecord:

Person.where("preferences->'diet'->'foods' ?| array[:foods]", foods: ['apples', 'mangos'])
...