3

Моя миграция выглядит следующим образом:Использование массивов postgres в Rails 4, как мне вернуть массив из всех уникальных элементов в массиве?

create table :posts do |t| 
    t.string :tags, array: true, default: [] 
end 

Как я могу получить массив всех уникальных тегов, сохраненных в тегах всех сообщений?

ответ

2

Я считаю, что вы могли бы также сделать это:

Post.pluck(:tags).flatten.uniq 

Если у вас есть тонна постов это может быть довольно значительным хитом на производительность, хотя ...

+0

Нет никакого способа обойти это: 'Post.pluck (: tags) .uniq' вернет все уникальные наборы тегов. Это нижняя сторона использования столбца массива вместо таблицы ассоциаций тегов «много-ко-многим». – tadman

+2

@tadman: Есть способы обойти его, PostgreSQL имеет довольно богатый набор массивов [операторов и функций] (http://www.postgresql.org/docs/current/interactive/functions-array.html). –

0

Как только я это, я нашел рабочий раствор, хотя может быть более элегантным способом решения этого:

Post.select(:tags).map(&:tags).flatten.uniq 

я был отброшен массивом объектов, решаемый с помощью .карта.

6

Вы можете сделать это внутри базы данных с:

select distinct unnest(tags) from posts 

Так что, если вы просто хотите строки, то вы можете перейти прямо к базе данных с:

tags = Post.connection.select_rows('select distinct unnest(tags) from posts').flatten 

Если существует много перекрытий между массивами tags или множеством массивов, то это должно быть быстрее, чем вытаскивать все массивы из базы данных и делать данные в Ruby.

+0

Я бы сказал, что этот ответ лучше моего. Я не был уверен в том, что метод запрашивает значение массива в базе данных, но я был уверен, что он существует. Я могу предложить попробовать немного изменить вызов, выполнив что-то вроде «Post.select (« DISTINCT disest (теги) AS uniq_tags »). Pluck (: uniq_tags) .flatten' -' select_rows' кажется немного хакерским способом получить от него. – nzifnab

+0

@nzifnab: вы могли бы обернуть все AR-файлы вокруг него, если хотите, но я так же комфортен с SQL, как и с Ruby, и я считаю, что обычное отношение «ничего, кроме Ruby» немного озадачивает; предположительно, вы все равно обернете это методом класса Post. Я не думаю, что вам понадобится этот «сгладить» вызов, вам нужно его с помощью 'select_rows', потому что он возвращает AoA, даже если каждая строка в наборе результатов имеет только одну запись. –

+0

Хорошая точка, не требуется сгладить. И в любом случае вы получите тот же результат. Полагаю, это вопрос предпочтения. – nzifnab

Смежные вопросы