Fix #1590: id metatag: "id:A..B,C..D,E"

Support searches like the following:

* score:<0,>100 (equivalent to `score:<0 or score:>100`)
* score:5,10..15,>20 (equivalent to `score:5 or score:10..15 or score:>20`)
* id:5,10..15,20..25,30 (equivalent to `id:5 or id:10..15 or id:20..25 or id:30`)

This also works inside the `search[id]` URL parameter, and inside other numeric
URL search parameters.
This commit is contained in:
evazion
2022-09-27 01:26:01 -05:00
parent 116c1f1af8
commit 331f15259a
3 changed files with 45 additions and 5 deletions

View File

@@ -15,6 +15,7 @@
# RangeParser.parse("5..10") => [:between, (5..10)]
# RangeParser.parse("5...10") => [:between, (5...10)]
# RangeParser.parse("5,6,7") => [:in, [5, 6, 7]]
# RangeParser.parse("5,7..9") => [:union, [[:eq, 5], [:between, (7..9)]]]
# RangeParser.parse("any") => [:not_eq, nil]
# RangeParser.parse("none") => [:eq, nil]
#
@@ -40,6 +41,10 @@ class RangeParser
range = case string
in _ if type == :enum
[:in, string.split(/[, ]+/).map { |x| parse_value(x) }]
in /[, ]/ if string.match?(/<|>|\.\./) # >A,<B,C..D
[:union, string.split(/[, ]+/).map { |x| RangeParser.parse(x, type) }]
in /[, ]/ # A,B,C
[:in, string.split(/[, ]+/).map { |x| parse_value(x) }]
in /\A(.+?)\.\.\.(.+)/ # A...B
lo, hi = [parse_value($1), parse_value($2)].sort
[:between, (lo...hi)]
@@ -54,8 +59,6 @@ class RangeParser
[:gteq, parse_value($1)]
in /\A>(.+)/ # >A
[:gt, parse_value($1)]
in /[, ]/ # A,B,C
[:in, string.split(/[, ]+/).map { |x| parse_value(x) }]
in "any"
[:not_eq, nil]
in "none"