forked from mastodon/mastodon
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add a new public status index * Create an importer for the new index * Try to add a vaccuum thing * quick lint * make sure that the settings are correct. TODO: add a test making sure the settings are set up correctly * One more easy one... * Hunt down all the status index usage except for the actual searching and the tests * consolidate and clean up a bit * forgot the end * Add new test * Move test to the right spot and try agian * clean up the test * use described_class instead and clean up the chewy fields a bit * What happens if you change your discoverable attribute * lint * rename the file * Just trying to make the build happy again... * it helps when you know what your methods are called * add an if here cause it seems a bit smarter * too many blank lines... * Seperate out into more than a single file * Make the public index really public * Add some new lines... * Try to dumb down the tests again so that I can get them to pass.... * gosh so many rules * annoying contrdictory rules...make a new method * I don't think this was working correctly * Add one more test and then I think I duplicated everything that I need to before adding any new tests (if I am doing that...) and actually implementing the search part of this * Update the public status importer * Try to do a better join...not sure that I really know what I'm doing at this point * Get this working. see if we can make it better... * Okay. I think this is the best I am going to do * add some new tests for the workers * Lint the tests and the files with them... * I think this is actually more correct * Add new test file for the new concern * lint * We need to override the chewy's strategy's callback so that if we have a status also try to write it to the public status. The chewy index will take care of the rest for us and figure out what should actually happen * Single quotes * Update the index the right way * Get searching working...I think * I think this is a more correct query
- Loading branch information
1 parent
8c53339
commit b7d4c84
Showing
20 changed files
with
559 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# frozen_string_literal: true | ||
|
||
class PublicStatusesIndex < Chewy::Index | ||
include FormattingHelper | ||
|
||
settings index: { refresh_interval: '30s' }, analysis: { | ||
filter: { | ||
english_stop: { | ||
type: 'stop', | ||
stopwords: '_english_', | ||
}, | ||
english_stemmer: { | ||
type: 'stemmer', | ||
language: 'english', | ||
}, | ||
english_possessive_stemmer: { | ||
type: 'stemmer', | ||
language: 'possessive_english', | ||
}, | ||
}, | ||
analyzer: { | ||
content: { | ||
tokenizer: 'uax_url_email', | ||
filter: %w( | ||
english_possessive_stemmer | ||
lowercase | ||
asciifolding | ||
cjk_width | ||
english_stop | ||
english_stemmer | ||
), | ||
}, | ||
}, | ||
} | ||
|
||
# We do not use delete_if option here because it would call a method that we | ||
# expect to be called with crutches without crutches, causing n+1 queries | ||
index_scope ::Status.unscoped | ||
.kept | ||
.without_reblogs | ||
.includes(:media_attachments, :preloadable_poll) | ||
.joins(:account) | ||
.where(accounts: { discoverable: true }) | ||
.where(visibility: :public) | ||
|
||
crutch :mentions do |collection| | ||
data = ::Mention.where(status_id: collection.map(&:id)).where(account: Account.local, silent: false).pluck(:status_id, :account_id) | ||
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } | ||
end | ||
|
||
crutch :favourites do |collection| | ||
data = ::Favourite.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id) | ||
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } | ||
end | ||
|
||
crutch :reblogs do |collection| | ||
data = ::Status.where(reblog_of_id: collection.map(&:id)).where(account: Account.local).pluck(:reblog_of_id, :account_id) | ||
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } | ||
end | ||
|
||
crutch :bookmarks do |collection| | ||
data = ::Bookmark.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id) | ||
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } | ||
end | ||
|
||
crutch :votes do |collection| | ||
data = ::PollVote.joins(:poll).where(poll: { status_id: collection.map(&:id) }).where(account: Account.local).pluck(:status_id, :account_id) | ||
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } | ||
end | ||
|
||
root date_detection: false do | ||
field(:id, type: 'long') | ||
field(:account_id, type: 'long') | ||
|
||
field(:text, type: 'text', value: ->(status) { status.searchable_text }) do | ||
field(:stemmed, type: 'text', analyzer: 'content') | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# frozen_string_literal: true | ||
|
||
class Importer::PublicStatusesIndexImporter < Importer::BaseImporter | ||
def import! | ||
# Similar to the StatusesIndexImporter, we will process different scopes | ||
# to import data into the PublicStatusesIndex. | ||
scopes.each do |scope| | ||
scope.find_in_batches(batch_size: @batch_size) do |batch| | ||
in_work_unit(batch.map(&:status_id)) do |status_ids| | ||
bulk = ActiveRecord::Base.connection_pool.with_connection do | ||
status_data = Status.includes(:media_attachments, :preloadable_poll) | ||
.joins(:account) | ||
.where(accounts: { discoverable: true }) | ||
.where(id: status_ids) | ||
Chewy::Index::Import::BulkBuilder.new(index, to_index: status_data).bulk_body | ||
end | ||
|
||
indexed = 0 | ||
deleted = 0 | ||
|
||
bulk.map! do |entry| | ||
if entry[:index] | ||
indexed += 1 | ||
else | ||
deleted += 1 | ||
end | ||
entry | ||
end | ||
|
||
Chewy::Index::Import::BulkRequest.new(index).perform(bulk) | ||
|
||
[indexed, deleted] | ||
end | ||
end | ||
end | ||
|
||
wait! | ||
end | ||
|
||
private | ||
|
||
def index | ||
PublicStatusesIndex | ||
end | ||
|
||
def scopes | ||
[ | ||
local_statuses_scope, | ||
local_mentions_scope, | ||
local_favourites_scope, | ||
local_votes_scope, | ||
local_bookmarks_scope, | ||
] | ||
end | ||
|
||
def local_mentions_scope | ||
Mention.where(account: Account.local, silent: false) | ||
.joins(status: :account) | ||
.where(accounts: { discoverable: true }) | ||
.where(statuses: { visibility: :public }) | ||
.select('mentions.id, statuses.id AS status_id') | ||
end | ||
|
||
def local_favourites_scope | ||
Favourite.where(account: Account.local) | ||
.joins(status: :account) | ||
.where(accounts: { discoverable: true }) | ||
.where(statuses: { visibility: :public }) | ||
.select('favourites.id, statuses.id AS status_id') | ||
end | ||
|
||
def local_bookmarks_scope | ||
Bookmark.joins(status: :account) | ||
.where(accounts: { discoverable: true }) | ||
.where(statuses: { visibility: :public }) | ||
.select('bookmarks.id, statuses.id AS status_id') | ||
end | ||
|
||
def local_votes_scope | ||
local_account_ids = Account.where(discoverable: true).pluck(:id) | ||
|
||
Poll.joins(:votes) | ||
.where(poll_votes: { account_id: local_account_ids }) | ||
.where(status_id: Status.where(visibility: :public)) | ||
end | ||
|
||
def local_statuses_scope | ||
Status.local | ||
.select('"statuses"."id", COALESCE("statuses"."reblog_of_id", "statuses"."id") AS status_id') | ||
.joins(:account) | ||
.where(accounts: { discoverable: true }) | ||
.where(visibility: :public) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# frozen_string_literal: true | ||
|
||
module AccountStatusesSearch | ||
extend ActiveSupport::Concern | ||
|
||
def enqueue_update_public_statuses_index | ||
if discoverable? | ||
enqueue_add_to_public_statuses_index | ||
else | ||
enqueue_remove_from_public_statuses_index | ||
end | ||
end | ||
|
||
def enqueue_add_to_public_statuses_index | ||
return unless Chewy.enabled? | ||
|
||
AddToPublicStatusesIndexWorker.perform_async(id) | ||
end | ||
|
||
def enqueue_remove_from_public_statuses_index | ||
return unless Chewy.enabled? | ||
|
||
RemoveFromPublicStatusesIndexWorker.perform_async(id) | ||
end | ||
|
||
def add_to_public_statuses_index! | ||
return unless Chewy.enabled? | ||
|
||
batch_size = 1000 | ||
offset = 0 | ||
|
||
loop do | ||
batch = Status.where(account_id: id).offset(offset).limit(batch_size) | ||
|
||
break if batch.empty? | ||
|
||
Chewy.strategy(:sidekiq) do | ||
PublicStatusesIndex.import(query: batch) | ||
end | ||
|
||
offset += batch_size | ||
end | ||
end | ||
|
||
def remove_from_public_statuses_index! | ||
return unless Chewy.enabled? | ||
|
||
PublicStatusesIndex.filter(term: { account_id: id }).delete_all | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.