~cytrogen/masto-fe

68b4e36c82344fba7c5a01e9f8dc9ddbaaf4e3ff — Eugen Rochko 2 years ago a106c46
Fix `#hashtag` matching non-hashtagged posts in search (#26781)

M app/chewy/public_statuses_index.rb => app/chewy/public_statuses_index.rb +12 -1
@@ 37,18 37,29 @@ class PublicStatusesIndex < Chewy::Index
          english_stemmer
        ),
      },

      hashtag: {
        tokenizer: 'keyword',
        filter: %w(
          word_delimiter_graph
          lowercase
          asciifolding
          cjk_width
        ),
      },
    },
  }

  index_scope ::Status.unscoped
                      .kept
                      .indexable
                      .includes(:media_attachments, :preloadable_poll, :preview_cards)
                      .includes(:media_attachments, :preloadable_poll, :preview_cards, :tags)

  root date_detection: false do
    field(:id, type: 'long')
    field(:account_id, type: 'long')
    field(:text, type: 'text', analyzer: 'verbatim', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') }
    field(:tags, type: 'text', analyzer: 'hashtag', value: ->(status) { status.tags.map(&:display_name) })
    field(:language, type: 'keyword')
    field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })
    field(:created_at, type: 'date')

M app/chewy/statuses_index.rb => app/chewy/statuses_index.rb +12 -1
@@ 37,15 37,26 @@ class StatusesIndex < Chewy::Index
          english_stemmer
        ),
      },

      hashtag: {
        tokenizer: 'keyword',
        filter: %w(
          word_delimiter_graph
          lowercase
          asciifolding
          cjk_width
        ),
      },
    },
  }

  index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preview_cards, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? }
  index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preview_cards, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, :tags, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? }

  root date_detection: false do
    field(:id, type: 'long')
    field(:account_id, type: 'long')
    field(:text, type: 'text', analyzer: 'verbatim', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') }
    field(:tags, type: 'text', analyzer: 'hashtag',  value: ->(status) { status.tags.map(&:display_name) })
    field(:searchable_by, type: 'long', value: ->(status) { status.searchable_by })
    field(:language, type: 'keyword')
    field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })

M app/chewy/tags_index.rb => app/chewy/tags_index.rb +15 -9
@@ 5,12 5,21 @@ class TagsIndex < Chewy::Index
    analyzer: {
      content: {
        tokenizer: 'keyword',
        filter: %w(lowercase asciifolding cjk_width),
        filter: %w(
          word_delimiter_graph
          lowercase
          asciifolding
          cjk_width
        ),
      },

      edge_ngram: {
        tokenizer: 'edge_ngram',
        filter: %w(lowercase asciifolding cjk_width),
        filter: %w(
          lowercase
          asciifolding
          cjk_width
        ),
      },
    },



@@ 30,12 39,9 @@ class TagsIndex < Chewy::Index
  end

  root date_detection: false do
    field :name, type: 'text', analyzer: 'content' do
      field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content'
    end

    field :reviewed, type: 'boolean', value: ->(tag) { tag.reviewed? }
    field :usage, type: 'long', value: ->(tag, crutches) { tag.history.aggregate(crutches.time_period).accounts }
    field :last_status_at, type: 'date', value: ->(tag) { tag.last_status_at || tag.created_at }
    field(:name, type: 'text', analyzer: 'content', value: :display_name) { field(:edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content') }
    field(:reviewed, type: 'boolean', value: ->(tag) { tag.reviewed? })
    field(:usage, type: 'long', value: ->(tag, crutches) { tag.history.aggregate(crutches.time_period).accounts })
    field(:last_status_at, type: 'date', value: ->(tag) { tag.last_status_at || tag.created_at })
  end
end

M app/lib/search_query_transformer.rb => app/lib/search_query_transformer.rb +5 -1
@@ 53,7 53,11 @@ class SearchQueryTransformer < Parslet::Transform
    end

    def to_query
      { multi_match: { type: 'most_fields', query: @term, fields: ['text', 'text.stemmed'], operator: 'and' } }
      if @term.start_with?('#')
        { match: { tags: { query: @term } } }
      else
        { multi_match: { type: 'most_fields', query: @term, fields: ['text', 'text.stemmed'], operator: 'and' } }
      end
    end
  end