Я делаю запрос к моей базе данных POSTGRESQL.В моем приложении есть статьи, а в статьях может быть несколько хэштегов.Эти отношения сохраняются в объединенной таблице хэштегов и статей.
У меня есть рабочий метод, который возвращает мне статьи, имеющие определенные хэштеги, или возвращает все статьи, которые не содержат определенные хэштеги
def test(hashtags, include = true)
articles= []
hashtags.split(' ').each do |h|
articles+= Article.joins(:hashtags).where('LOWER(hashtags.value) LIKE LOWER(?)', "#{h}")
end
if include
articles.uniq
else
(Article.all.to_set - articles.uniq.to_set).to_a
end
end
Я мог бы назвать это так:
test("politics people china", true)
И это дало бы мне все статьи, у которых есть один из тех хэштегов, связанных с
Или я мог бы так назвать
test("politics people china", false)
И это дало бы мне все статьи, КРОМЕ тех, у кого есть один из этих хэштегов
Это работает хорошо, но я не думаю, что это очень эффективно, так как я делаю так много в Ruby, а нена уровне БД.
Я пробовал это:
def test2(hashtags, include = true)
articles= []
pattern = ''
hashtags.split(' ').each do |h|
pattern += "#{h}|"
end
pattern = '(' + pattern[0...-1] + ')'
if include
articles = Article.joins(:hashtags).where('hashtags.value ~* ?', "#{pattern}")
else
articles = Article.joins(:hashtags).where('hashtags.value !~* ?', "#{pattern}")
end
articles.uniq
end
Но он не ведет себя так, как я думал, что будет.Прежде всего, если я назову это так:
test2("politics china", true)
Это даст мне не только все статьи с хэштегами politics
или china
, но и все статьи, у которых есть хэштег, содержащий одинбукв в politics
или china
примерно так:
(p|o|l|i|t|c|s|h|n|a)
, но он должен проверять это на самом деле, и шаблон выглядит на самом деле так, что я вижу в консоли:
(politics|china)
что он не находит то, что я нахожу странным ...
И с
test2("politics", false)
Это дает мне только статьи, с которыми связан один или несколько хэштегов, НОпропускает тех, у кого вообще нет хэштега
Может ли кто-нибудь помочь мне сделать мой метод работы более эффективным?
РЕДАКТИРОВАТЬ: Вот мой обновленный код, как предложено в ответе
def test2(hashtags, include = false)
hashtags =
if include
Hashtag.where("LOWER(value) iLIKE ANY ( array[?] )", hashtags)
else
Hashtag.where("LOWER(value) NOT iLIKE ANY ( array[?] )", hashtags)
end
Slot.joins(:hashtags).merge(hashtags).distinct
end
Мне все еще не хватает статей, у которых вообще нет НИКАКИХ хэштегов, если, к сожалению, incude
неверно