Update indexer, add scope switch

main
Vyr Cossont 2 years ago
parent 494d98c3a8
commit 98c9bc52c0

@ -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)

@ -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…
Cancel
Save