This is an automated email from the ASF dual-hosted git repository.
janhoy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-orbit.git
The following commit(s) were added to refs/heads/main by this push:
new 741b8501 Preserve range bound inclusivity when translating to Solr
(#69)
741b8501 is described below
commit 741b8501b0f33c5b0a68cca4b03403e932cf6516
Author: Serhiy Bzhezytskyy <[email protected]>
AuthorDate: Thu Sep 3 20:34:43 2026 +0300
Preserve range bound inclusivity when translating to Solr (#69)
---
solrorbit/conversion/query.py | 17 ++++++++++++++---
tests/unit/solr/test_workload_converter.py | 21 +++++++++++++++++----
2 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/solrorbit/conversion/query.py b/solrorbit/conversion/query.py
index 5b4b2766..432b22b0 100644
--- a/solrorbit/conversion/query.py
+++ b/solrorbit/conversion/query.py
@@ -181,13 +181,24 @@ def _translate_query_node(node: dict, fq_list: list =
None) -> str:
if "range" in node:
for field, bounds in node["range"].items():
field = normalize_field_name(field)
- lo = bounds.get("gte", bounds.get("gt", "*"))
- hi = bounds.get("lte", bounds.get("lt", "*"))
+ # gt/lt are exclusive; Solr spells that with a curly bracket.
+ if "gte" in bounds:
+ lo, lo_bracket = bounds["gte"], "["
+ elif "gt" in bounds:
+ lo, lo_bracket = bounds["gt"], "{"
+ else:
+ lo, lo_bracket = "*", "["
+ if "lte" in bounds:
+ hi, hi_bracket = bounds["lte"], "]"
+ elif "lt" in bounds:
+ hi, hi_bracket = bounds["lt"], "}"
+ else:
+ hi, hi_bracket = "*", "]"
# Convert dates if format is specified (common for date fields)
os_format = bounds.get("format")
lo = _convert_date_to_solr_format(lo, os_format)
hi = _convert_date_to_solr_format(hi, os_format)
- return f"{field}:[{lo} TO {hi}]"
+ return f"{field}:{lo_bracket}{lo} TO {hi}{hi_bracket}"
if "exists" in node:
field = node["exists"].get("field", "*")
diff --git a/tests/unit/solr/test_workload_converter.py
b/tests/unit/solr/test_workload_converter.py
index 1927a4cf..423dc9c7 100644
--- a/tests/unit/solr/test_workload_converter.py
+++ b/tests/unit/solr/test_workload_converter.py
@@ -209,11 +209,24 @@ class TestTranslateToSolrJsonDsl(unittest.TestCase):
result = translate_to_solr_json_dsl(body)
self.assertIn("vendor_id", result["query"])
+ def _range(self, bounds):
+ return translate_to_solr_json_dsl(
+ {"query": {"range": {"fare_amount": bounds}}})["query"]
+
def test_range_query(self):
- body = {"query": {"range": {"fare_amount": {"gte": 5, "lte": 100}}}}
- result = translate_to_solr_json_dsl(body)
- self.assertIn("fare_amount", result["query"])
- self.assertIn("TO", result["query"])
+ self.assertEqual("fare_amount:[5 TO 100]", self._range({"gte": 5,
"lte": 100}))
+
+ def test_exclusive_bounds_use_curly_brackets(self):
+ self.assertEqual("fare_amount:[5 TO 100}", self._range({"gte": 5,
"lt": 100}))
+ self.assertEqual("fare_amount:{5 TO 100]", self._range({"gt": 5,
"lte": 100}))
+ self.assertEqual("fare_amount:{5 TO 100}", self._range({"gt": 5, "lt":
100}))
+
+ def test_a_missing_bound_is_open_and_inclusive(self):
+ # An absent bound is `*`, which has nothing to exclude.
+ self.assertEqual("fare_amount:[5 TO *]", self._range({"gte": 5}))
+ self.assertEqual("fare_amount:{5 TO *]", self._range({"gt": 5}))
+ self.assertEqual("fare_amount:[* TO 100}", self._range({"lt": 100}))
+ self.assertEqual("fare_amount:[* TO 100]", self._range({"lte": 100}))
def test_bool_with_filter_goes_to_fq(self):
body = {