Fix not being able to negate prefix clauses in search (#26672)

main
Eugen Rochko 2023-08-28 10:31:51 +02:00 committed by GitHub
parent fc14d1f3b0
commit 822a35b9d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 4 deletions

View File

@ -9,7 +9,7 @@ class SearchQueryParser < Parslet::Parser
rule(:prefix) { (term >> colon).as(:prefix) } rule(:prefix) { (term >> colon).as(:prefix) }
rule(:shortcode) { (colon >> term >> colon.maybe).as(:shortcode) } rule(:shortcode) { (colon >> term >> colon.maybe).as(:shortcode) }
rule(:phrase) { (quote >> (term >> space.maybe).repeat >> quote).as(:phrase) } rule(:phrase) { (quote >> (term >> space.maybe).repeat >> quote).as(:phrase) }
rule(:clause) { (prefix.maybe >> operator.maybe >> (phrase | term | shortcode)).as(:clause) } rule(:clause) { (operator.maybe >> prefix.maybe >> (phrase | term | shortcode)).as(:clause) }
rule(:query) { (clause >> space.maybe).repeat.as(:query) } rule(:query) { (clause >> space.maybe).repeat.as(:query) }
root(:query) root(:query)
end end

View File

@ -36,7 +36,11 @@ class SearchQueryTransformer < Parslet::Transform
def clause_to_filter(clause) def clause_to_filter(clause)
case clause case clause
when PrefixClause when PrefixClause
{ clause.type => { clause.filter => clause.term } } if clause.negated?
{ bool: { must_not: { clause.type => { clause.filter => clause.term } } } }
else
{ clause.type => { clause.filter => clause.term } }
end
else else
raise "Unexpected clause type: #{clause}" raise "Unexpected clause type: #{clause}"
end end
@ -81,7 +85,8 @@ class SearchQueryTransformer < Parslet::Transform
class PrefixClause class PrefixClause
attr_reader :type, :filter, :operator, :term attr_reader :type, :filter, :operator, :term
def initialize(prefix, term) def initialize(prefix, operator, term)
@negated = operator == '-'
@operator = :filter @operator = :filter
case prefix case prefix
@ -114,6 +119,10 @@ class SearchQueryTransformer < Parslet::Transform
end end
end end
def negated?
@negated
end
private private
def account_id_from_term(term) def account_id_from_term(term)
@ -132,7 +141,7 @@ class SearchQueryTransformer < Parslet::Transform
operator = clause[:operator]&.to_s operator = clause[:operator]&.to_s
if clause[:prefix] if clause[:prefix]
PrefixClause.new(prefix, clause[:term].to_s) PrefixClause.new(prefix, operator, clause[:term].to_s)
elsif clause[:term] elsif clause[:term]
TermClause.new(prefix, operator, clause[:term].to_s) TermClause.new(prefix, operator, clause[:term].to_s)
elsif clause[:shortcode] elsif clause[:shortcode]