statuses_index_importer.rb 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. # frozen_string_literal: true
  2. class Importer::StatusesIndexImporter < Importer::BaseImporter
  3. def import!
  4. # The idea is that instead of iterating over all statuses in the database
  5. # and calculating the searchable_by for each of them (majority of which
  6. # would be empty), we approach the index from the other end
  7. scopes.each do |scope|
  8. # We could be tempted to keep track of status IDs we have already processed
  9. # from a different scope to avoid indexing them multiple times, but that
  10. # could end up being a very large array
  11. scope.reorder(nil).find_in_batches(batch_size: @batch_size) do |tmp|
  12. in_work_unit(tmp.map(&:status_id)) do |status_ids|
  13. deleted = 0
  14. bulk = ActiveRecord::Base.connection_pool.with_connection do
  15. to_index = index.adapter.default_scope.where(id: status_ids)
  16. crutches = Chewy::Index::Crutch::Crutches.new index, to_index
  17. to_index.map do |object|
  18. # This is unlikely to happen, but the post may have been
  19. # un-interacted with since it was queued for indexing
  20. if object.searchable_by.empty?
  21. deleted += 1
  22. { delete: { _id: object.id } }
  23. else
  24. { index: { _id: object.id, data: index.compose(object, crutches, fields: []) } }
  25. end
  26. end
  27. end
  28. indexed = bulk.size - deleted
  29. Chewy::Index::Import::BulkRequest.new(index).perform(bulk)
  30. [indexed, deleted]
  31. end
  32. end
  33. end
  34. wait!
  35. end
  36. private
  37. def index
  38. StatusesIndex
  39. end
  40. def scopes
  41. [
  42. local_statuses_scope,
  43. local_mentions_scope,
  44. local_favourites_scope,
  45. local_votes_scope,
  46. local_bookmarks_scope,
  47. ]
  48. end
  49. def local_mentions_scope
  50. Mention.where(account: Account.local, silent: false).select(:id, :status_id)
  51. end
  52. def local_favourites_scope
  53. Favourite.where(account: Account.local).select(:id, :status_id)
  54. end
  55. def local_bookmarks_scope
  56. Bookmark.select(:id, :status_id)
  57. end
  58. def local_votes_scope
  59. Poll.joins(:votes).where(votes: { account: Account.local }).select('polls.id, polls.status_id')
  60. end
  61. def local_statuses_scope
  62. Status.local.select('"statuses"."id", COALESCE("statuses"."reblog_of_id", "statuses"."id") AS status_id')
  63. end
  64. end