From 26d465175aee2aab7190f2eb9fa02a2a752b571b Mon Sep 17 00:00:00 2001 From: Vyr Cossont Date: Fri, 30 Dec 2022 12:48:23 -0800 Subject: [PATCH] Add sort operator, default to newest first --- app/chewy/statuses_index.rb | 1 + app/lib/search_query_transformer.rb | 34 ++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb index d779a226a2..e6f9a04c30 100644 --- a/app/chewy/statuses_index.rb +++ b/app/chewy/statuses_index.rb @@ -65,6 +65,7 @@ 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 :text, type: 'text', value: ->(status) { status.searchable_text } do diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb index aef05e9d9d..d1671459c1 100644 --- a/app/lib/search_query_transformer.rb +++ b/app/lib/search_query_transformer.rb @@ -2,7 +2,7 @@ class SearchQueryTransformer < Parslet::Transform class Query - attr_reader :should_clauses, :must_not_clauses, :must_clauses, :filter_clauses + attr_reader :should_clauses, :must_not_clauses, :must_clauses, :filter_clauses, :order_clauses def initialize(clauses) grouped = clauses.chunk(&:operator).to_h @@ -10,6 +10,7 @@ class SearchQueryTransformer < Parslet::Transform @must_not_clauses = grouped.fetch(:must_not, []) @must_clauses = grouped.fetch(:must, []) @filter_clauses = grouped.fetch(:filter, []) + @order_clauses = grouped.fetch(:order, []) end def apply(search) @@ -17,6 +18,12 @@ class SearchQueryTransformer < Parslet::Transform must_clauses.each { |clause| search = search.query.must(clause_to_query(clause)) } must_not_clauses.each { |clause| search = search.query.must_not(clause_to_query(clause)) } filter_clauses.each { |clause| search = search.filter(**clause_to_filter(clause)) } + if order_clauses.empty? + # Default to most recent results first. + search = search.order(created_at: :desc) + else + order_clauses.each { |clause| search = search.order(**clause_to_order(clause)) } + end search.query.minimum_should_match(1) end @@ -41,6 +48,15 @@ class SearchQueryTransformer < Parslet::Transform raise "Unexpected clause type: #{clause}" end end + + def clause_to_order(clause) + case clause + when PrefixClause + { clause.term => clause.order } + else + raise "Unexpected clause type: #{clause}" + end + end end class Operator @@ -81,12 +97,12 @@ class SearchQueryTransformer < Parslet::Transform end class PrefixClause - attr_reader :filter, :operator, :term + attr_reader :filter, :operator, :term, :order def initialize(prefix, term) - @operator = :filter case prefix when 'from' + @operator = :filter @filter = :account_id username, domain = term.gsub(/\A@/, '').split('@') @@ -94,6 +110,18 @@ class SearchQueryTransformer < Parslet::Transform account = Account.find_remote!(username, domain) @term = account.id + when 'sort' + @operator = :order + @term = :created_at + + case term + when 'oldest' + @order = :asc + when 'newest' + @order = :desc + else + raise Mastodon::SyntaxError + end else raise Mastodon::SyntaxError end