Настройте pg_search так, чтобы отображался только контент текущего пользователя

У меня есть многопользовательский сайт, и я хочу, чтобы пользователи могли выполнять полнотекстовый многомодельный поиск только по своему собственному контенту.

Моя рабочая модель принадлежит_кому: :users. Вот фрагмент work.rb:

class Work < ApplicationRecord
  include PgSearch
  belongs_to :user
  …

Идеальным сценарием в моем контроллере было бы что-то вроде этого:

@results = PgSearch.multisearch('spring').where(:_user_id => current_user.id)

Я смог легко сделать это с помощью драгоценного камня Searchkick с Elasticsearch, используя эту строку кода:

@results = Searchkick.search query, where: {user_id: current_user.id}

К сожалению, я больше не могу использовать Elasticsearch.

Как я могу реализовать аналогичную функциональность в pg_search?

Большое спасибо


person Dauncing    schedule 10.10.2017    source источник


Ответы (2)


Я только начинаю работать с PgSearch, но, судя по тому, что я вижу, вы можете применять фильтры только к тем данным, которые отправляются в их базу данных pg_search_documents. Таким образом, вы не можете изолировать конкретного пользователя для поиска, который вы выполняете позже. Они просто объединяют различные поля в свое поле содержимого и ссылаются на модель и запись, из которой они получены. Это позволяет легко выполнять поиск записей, соответствующих критериям, но тогда вам придется выполнять постобработку данных.

Чтобы сделать то, что вы предлагаете, потребуется создать таблицу поиска для каждого пользователя.

если вы включите user_id в свои критерии против (должен быть в контенте), вы можете быстро опубликовать обработку данных, поскольку идентификатор будет в контенте. Если он находится в конце списка :against, он будет в конце содержимого, поэтому вы можете быстро удалить его и обработать против него.

person bobbdelsol    schedule 08.11.2017
comment
Теперь для этого есть встроенная в pg_search функция дополнительных_атрибутов — github.com/Casecommons/pg_search #дополнительные параметры - person Dauncing; 17.09.2019

Вы можете использовать pg_search_scope, как описано в pg_search_scope.

в вашем случае это мультипоиск pg_search_scope

person sukorenomw    schedule 11.10.2017
comment
Я попробовал аналогичный подход, уже используя атрибут :if. Проблема в том, что мне нужно будет вызвать current_user из моей модели. Мне удалось получить объект current_user внутри модели с помощью пользовательского модуля, хотя вы и не должны этого делать, но это сломало функцию индексации поиска. multisearchable :against => [:title, :year, :user_id], :if => lambda { |record| record.user_id == Current.user.id } Может быть, у вас был более элегантный способ сделать это внутри модели? Спасибо еще раз - person Dauncing; 12.10.2017
comment
У меня есть обходной путь, но я думаю, что он не будет хорошо работать в масштабе. Следующий код можно загрузить в контроллер поиска results = PgSearch.multisearch(query).map(&:searchable).select{|record| record.user_id == current_user.id }.sort_by(&sortField.to_sym) Хотелось бы более элегантное решение, если кто-нибудь может что-то предложить. - person Dauncing; 12.10.2017