about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authormultiple creatures <dev@multiple-creature.party>2019-04-13 23:17:51 -0500
committermultiple creatures <dev@multiple-creature.party>2019-05-21 03:16:21 -0500
commitdd5e02ad5d79e4fc2163a9bcd009859e9c2a4466 (patch)
treef8d2aa407ff53805408f0cbc17d7d25a7f28ea23 /app
parent4c170d2a98e4a289ad40580785cbeb892bd68eab (diff)
Use PostgreSQL FTS for searches.
Diffstat (limited to 'app')
-rw-r--r--app/controllers/api/v1/search_controller.rb2
-rw-r--r--app/models/status.rb17
-rw-r--r--app/services/search_service.rb1
3 files changed, 19 insertions, 1 deletions
diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb
index 6131cbbb6..194e7c810 100644
--- a/app/controllers/api/v1/search_controller.rb
+++ b/app/controllers/api/v1/search_controller.rb
@@ -3,7 +3,7 @@
 class Api::V1::SearchController < Api::BaseController
   include Authorization
 
-  RESULTS_LIMIT = 20
+  RESULTS_LIMIT = 33
 
   before_action -> { doorkeeper_authorize! :read, :'read:search' }
   before_action :require_user!
diff --git a/app/models/status.rb b/app/models/status.rb
index 45db988e3..7679fd60f 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -298,6 +298,23 @@ class Status < ApplicationRecord
   after_find :limit_domain_visibility
 
   class << self
+    def search_for(term, limit = 33, account = nil)
+      pattern = sanitize_sql_like(term)
+      pattern = "#{pattern}"
+      Status.unscoped {
+        scope = Status.where("tsv @@ plainto_tsquery('english', ?)", pattern)
+        query = scope.where(visibility: :public)
+        if account.present?
+          query = query
+            .or(scope.where(account: account))
+            .or(scope.where(account: account.following, visibility: [:unlisted, :private]))
+            .or(scope.where(id: account.mentions.select(:status_id)))
+        end
+        query = query.where(reblog_of_id: nil).order(id: :desc).limit(limit)
+        apply_timeline_filters(query, account, true)
+      }
+    end
+
     def selectable_visibilities
       visibilities.keys - %w(direct limited)
     end
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index e0da61dac..1ba2f227f 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -16,6 +16,7 @@ class SearchService < BaseService
         results[:accounts] = perform_accounts_search! if account_searchable?
         results[:statuses] = perform_statuses_search! if full_text_searchable?
         results[:hashtags] = perform_hashtags_search! if hashtag_searchable?
+        results[:statuses] = Status.search_for(query.gsub(/\A#/, ''), limit, account) unless query.start_with?('@') or query.start_with?('#')
       end
     end
   end