Используя массивы JSON в столбце jsonb
в Postgres 9.4 и Rails, я могу настроить область, которая возвращает все строки, содержащие любые элементы из массива, переданного методу области видимости:
scope :tagged, ->(tags) {
where(["data->'tags' ?| ARRAY[:tags]", { tags: tags }])
}
Я также хотел бы заказать результаты на основе количества согласованных элементов в массиве.
Я ценю, что мне, возможно, нужно выйти за пределы ActiveRecord, чтобы сделать это, поэтому полезно ответить на ответ ванили Postgres SQL, но бонусные баллы, если он может быть обернут в ActiveRecord, чтобы он мог быть охватом цепочки.
В соответствии с запросом, вот примерная таблица. (Фактическая схема намного сложнее, но это все, о чем я беспокоюсь.)
id | data
----+-----------------------------------
1 | {"tags": ["foo", "bar", "baz"]}
2 | {"tags": ["bish", "bash", "baz"]}
3 |
4 | {"tags": ["foo", "foo", "foo"]}
Вариант использования - найти связанный контент на основе тегов. Более подходящие теги более актуальны, поэтому результаты должны быть заказаны по количеству совпадений. В Ruby у меня был бы простой способ:
Page.tagged(['foo', 'bish', 'bash', 'baz']).all
Которые должны возвращать страницы в следующем порядке: 2, 1, 4
.