search: add exclusive range syntax (id:5...10).

Support exclusive ranges for numeric metatags. For example, `id:5...10`
is equivalent to `id:>=5 id:<10`. Useful for splitting searches into id
ranges without the endpoints overlapping: id:100...200, id:200...300,
id:300...400.
This commit is contained in:
evazion
2020-04-20 02:31:36 -05:00
parent 25159bb21c
commit c452aa6c78
2 changed files with 9 additions and 2 deletions

View File

@@ -1145,6 +1145,9 @@ class PostQueryBuilder
def parse_range(string, type = :integer)
range = case string
when /\A(.+?)\.\.\.(.+)/ # A...B
lo, hi = [parse_cast($1, type), parse_cast($2, type)].sort
[:between, (lo...hi)]
when /\A(.+?)\.\.(.+)/
lo, hi = [parse_cast($1, type), parse_cast($2, type)].sort
[:between, (lo..hi)]

View File

@@ -141,8 +141,12 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match([posts[2], posts[1]], "id:>=#{posts[1].id}")
assert_tag_match([posts[1], posts[0]], "id:<=#{posts[1].id}")
assert_tag_match([posts[2], posts[0]], "id:#{posts[0].id},#{posts[2].id}")
assert_tag_match(posts.reverse, "id:#{posts[0].id}..#{posts[2].id}")
assert_tag_match(posts.reverse, "id:#{posts[2].id}..#{posts[0].id}")
assert_tag_match([posts[2], posts[1]], "id:#{posts[1].id}..")
assert_tag_match([posts[1], posts[0]], "id:..#{posts[1].id}")
assert_tag_match([posts[1], posts[0]], "id:#{posts[0].id}..#{posts[1].id}")
assert_tag_match([posts[1], posts[0]], "id:#{posts[1].id}..#{posts[0].id}")
assert_tag_match([posts[1], posts[0]], "id:#{posts[0].id}...#{posts[2].id}")
assert_tag_match([], "id:#{posts[0].id} id:#{posts[2].id}")
assert_tag_match([posts[1]], "id:>#{posts[0].id} id:<#{posts[2].id}")