Update indexer, add scope switch
This commit is contained in:
		
							parent
							
								
									494d98c3a8
								
							
						
					
					
						commit
						98c9bc52c0
					
				
					 6 changed files with 47 additions and 11 deletions
				
			
		|  | @ -238,7 +238,7 @@ SMTP_FROM_ADDRESS=notifications@example.com | |||
| # SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.16.840.1.113730.3.1.241" | ||||
| # SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME="urn:oid:2.5.4.42" | ||||
| # SAML_ATTRIBUTES_STATEMENTS_LAST_NAME="urn:oid:2.5.4.4" | ||||
| # SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1" | ||||
| # SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1" | ||||
| # SAML_ATTRIBUTES_STATEMENTS_VERIFIED= | ||||
| # SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL= | ||||
| 
 | ||||
|  | @ -283,10 +283,11 @@ MAX_POLL_OPTION_CHARS=100 | |||
| # Customize the number of hashtags shown in 'Explore' | ||||
| # MAX_TRENDING_TAGS=10 | ||||
| 
 | ||||
| # Search all public statuses | ||||
| # (Normally searches only a user's own statuses, favs, bookmarks, and mentions) | ||||
| # Only relevant when elasticsearch is installed | ||||
| # SEARCH_ALL_PUBLIC_STATUSES=true | ||||
| # Scope of full-text searches: | ||||
| # - public: search any status with public visibility | ||||
| # - public_or_unlisted: search any status with public or unlisted visibility | ||||
| # - classic: searches only a user's own statuses, favs, bookmarks, and mentions | ||||
| # SEARCH_SCOPE=public | ||||
| 
 | ||||
| # Maximum custom emoji file sizes | ||||
| # If undefined or smaller than MAX_EMOJI_SIZE, the value | ||||
|  |  | |||
|  | @ -65,12 +65,15 @@ class StatusesIndex < Chewy::Index | |||
|   root date_detection: false do | ||||
|     field :id, type: 'long' | ||||
|     field :account_id, type: 'long' | ||||
|     field :created_at, type: 'date' | ||||
|     field :visibility, type: 'keyword' | ||||
|     field :from, type: 'keyword', value: ->(status) { status.account.domain ? [status.account.acct] : [status.account.acct, "#{status.account.username}@#{Rails.configuration.x.local_domain}"] } | ||||
|     field :domain, value: ->(status) { status.account.domain or Rails.configuration.x.local_domain } | ||||
| 
 | ||||
|     field :text, type: 'text', value: ->(status) { status.searchable_text } do | ||||
|       field :stemmed, type: 'text', analyzer: 'content' | ||||
|     end | ||||
| 
 | ||||
|     field :searchable_by, type: 'long', value: ->(status, crutches) { status.searchable_by(crutches) } | ||||
|     field :searchable_by_anyone, type: 'boolean', value: ->(status) { status.public_visibility? } | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -58,13 +58,21 @@ class Importer::StatusesIndexImporter < Importer::BaseImporter | |||
|   end | ||||
| 
 | ||||
|   def scopes | ||||
|     [ | ||||
|     classic_scopes = [ | ||||
|       local_statuses_scope, | ||||
|       local_mentions_scope, | ||||
|       local_favourites_scope, | ||||
|       local_votes_scope, | ||||
|       local_bookmarks_scope, | ||||
|     ] | ||||
|     case Rails.configuration.x.search_scope | ||||
|     when :public | ||||
|       classic_scopes + [public_scope] | ||||
|     when :public_or_unlisted | ||||
|       classic_scopes + [public_or_unlisted_scope] | ||||
|     else | ||||
|       classic_scopes | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def local_mentions_scope | ||||
|  | @ -86,4 +94,14 @@ class Importer::StatusesIndexImporter < Importer::BaseImporter | |||
|   def local_statuses_scope | ||||
|     Status.local.select('"statuses"."id", COALESCE("statuses"."reblog_of_id", "statuses"."id") AS status_id') | ||||
|   end | ||||
| 
 | ||||
|   # The `id` field in the above queries isn't used anywhere, so we leave it out of these. | ||||
| 
 | ||||
|   def public_scope | ||||
|     Status.with_public_visibility.select('"statuses"."id" AS status_id') | ||||
|   end | ||||
| 
 | ||||
|   def public_or_unlisted_scope | ||||
|     Status.with_public_or_unlisted_visibility.select('"statuses"."id" AS status_id') | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -99,6 +99,7 @@ class Status < ApplicationRecord | |||
|   scope :without_replies, -> { where('statuses.reply = FALSE OR statuses.in_reply_to_account_id = statuses.account_id') } | ||||
|   scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') } | ||||
|   scope :with_public_visibility, -> { where(visibility: :public) } | ||||
|   scope :with_public_or_unlisted_visibility, -> { where(visibility: [:public, :unlisted]) } | ||||
|   scope :tagged_with, ->(tag_ids) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag_ids }) } | ||||
|   scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced_at: nil }) } | ||||
|   scope :including_silenced_accounts, -> { left_outer_joins(:account).where.not(accounts: { silenced_at: nil }) } | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| # frozen_string_literal: true | ||||
| 
 | ||||
| class SearchService < BaseService | ||||
|   SEARCH_ALL_PUBLIC_STATUSES = ENV['SEARCH_ALL_PUBLIC_STATUSES'] == 'true' | ||||
| 
 | ||||
|   def call(query, account, limit, options = {}) | ||||
|     @query   = query&.strip | ||||
|     @account = account | ||||
|  | @ -38,8 +36,11 @@ class SearchService < BaseService | |||
| 
 | ||||
|   def perform_statuses_search! | ||||
|     statuses_index = StatusesIndex.filter(term: { searchable_by: @account.id }) | ||||
|     if SEARCH_ALL_PUBLIC_STATUSES | ||||
|       statuses_index = statuses_index.filter.or(term: { searchable_by_anyone: true }) | ||||
|     case Rails.configuration.x.search_scope | ||||
|     when :public | ||||
|       statuses_index = statuses_index.filter.or(term: { visibility: 'public' }) | ||||
|     when :public_or_unlisted | ||||
|       statuses_index = statuses_index.filter.or(term: { visibility: ['public', 'unlisted'] }) | ||||
|     end | ||||
|     definition = parsed_query.apply(statuses_index) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										12
									
								
								config/initializers/search_scope.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								config/initializers/search_scope.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| # frozen_string_literal: true | ||||
| 
 | ||||
| Rails.application.configure do | ||||
|   config.x.search_scope = case | ||||
|   when ENV['SEARCH_SCOPE'] == 'public' | ||||
|     :public | ||||
|   when ENV['SEARCH_SCOPE'] == 'public_or_unlisted' | ||||
|     :public_or_unlisted | ||||
|   else | ||||
|     :classic | ||||
|   end | ||||
| end | ||||
		Loading…
	
		Reference in a new issue