diff --git a/tests/unit/test_q.py b/tests/unit/test_q.py index 4122c441..4ae60351 100644 --- a/tests/unit/test_q.py +++ b/tests/unit/test_q.py @@ -1,5 +1,5 @@ import unittest -from vespa.querybuilder import Query, Q, Queryfield, G, Condition +from vespa.querybuilder import G import vespa.querybuilder as qb @@ -16,49 +16,49 @@ def test_dotProduct_with_annotations(self): return q def test_geolocation_with_annotations(self): - condition = Q.geoLocation( + condition = qb.geoLocation( "location_field", 37.7749, -122.4194, "10km", annotations={"targetHits": 100}, ) - q = Query(select_fields="*").from_("sd1").where(condition) + q = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where ({targetHits:100}geoLocation(location_field, 37.7749, -122.4194, "10km"))' self.assertEqual(q, expected) return q def test_select_specific_fields(self): - f1 = Queryfield("f1") + f1 = qb.Queryfield("f1") condition = f1.contains("v1") - q = Query(select_fields=["f1", "f2"]).from_("sd1").where(condition) + q = qb.select(["f1", "f2"]).from_("sd1").where(condition) self.assertEqual(q, 'select f1, f2 from sd1 where f1 contains "v1"') return q def test_select_from_specific_sources(self): - f1 = Queryfield("f1") + f1 = qb.Queryfield("f1") condition = f1.contains("v1") - q = Query(select_fields="*").from_("sd1").where(condition) + q = qb.select("*").from_("sd1").where(condition) self.assertEqual(q, 'select * from sd1 where f1 contains "v1"') return q def test_select_from_multiples_sources(self): - f1 = Queryfield("f1") + f1 = qb.Queryfield("f1") condition = f1.contains("v1") - q = Query(select_fields="*").from_("sd1", "sd2").where(condition) + q = qb.select("*").from_("sd1", "sd2").where(condition) self.assertEqual(q, 'select * from sd1, sd2 where f1 contains "v1"') return q def test_basic_and_andnot_or_offset_limit_param_order_by_and_contains(self): - f1 = Queryfield("f1") - f2 = Queryfield("f2") - f3 = Queryfield("f3") - f4 = Queryfield("f4") + f1 = qb.Queryfield("f1") + f2 = qb.Queryfield("f2") + f3 = qb.Queryfield("f3") + f4 = qb.Queryfield("f4") condition = ((f1.contains("v1") & f2.contains("v2")) | f3.contains("v3")) & ( ~f4.contains("v4") ) q = ( - Query(select_fields="*") + qb.select("*") .from_("sd1") .where(condition) .set_offset(1) @@ -73,59 +73,55 @@ def test_basic_and_andnot_or_offset_limit_param_order_by_and_contains(self): return q def test_timeout(self): - f1 = Queryfield("title") + f1 = qb.Queryfield("title") condition = f1.contains("madonna") - q = Query(select_fields="*").from_("sd1").where(condition).set_timeout(70) + q = qb.select("*").from_("sd1").where(condition).set_timeout(70) expected = 'select * from sd1 where title contains "madonna" timeout 70' self.assertEqual(q, expected) return q def test_matches(self): condition = ( - (Queryfield("f1").matches("v1") & Queryfield("f2").matches("v2")) - | Queryfield("f3").matches("v3") - ) & ~Queryfield("f4").matches("v4") - q = Query(select_fields="*").from_("sd1").where(condition) + (qb.Queryfield("f1").matches("v1") & qb.Queryfield("f2").matches("v2")) + | qb.Queryfield("f3").matches("v3") + ) & ~qb.Queryfield("f4").matches("v4") + q = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where ((f1 matches "v1" and f2 matches "v2") or f3 matches "v3") and !(f4 matches "v4")' self.assertEqual(q, expected) return q def test_nested_queries(self): nested_query = ( - Queryfield("f2").contains("2") & Queryfield("f3").contains("3") - ) | (Queryfield("f2").contains("4") & ~Queryfield("f3").contains("5")) - condition = Queryfield("f1").contains("1") & ~nested_query - q = Query(select_fields="*").from_("sd1").where(condition) + qb.Queryfield("f2").contains("2") & qb.Queryfield("f3").contains("3") + ) | (qb.Queryfield("f2").contains("4") & ~qb.Queryfield("f3").contains("5")) + condition = qb.Queryfield("f1").contains("1") & ~nested_query + q = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where f1 contains "1" and (!((f2 contains "2" and f3 contains "3") or (f2 contains "4" and !(f3 contains "5"))))' self.assertEqual(q, expected) return q def test_userquery(self): - condition = Q.userQuery() - q = Query(select_fields="*").from_("sd1").where(condition) + condition = qb.userQuery() + q = qb.select("*").from_("sd1").where(condition) expected = "select * from sd1 where userQuery()" self.assertEqual(q, expected) return q def test_fields_duration(self): - f1 = Queryfield("subject") - f2 = Queryfield("display_date") - f3 = Queryfield("duration") - q = Query(select_fields=[f1, f2]).from_("calendar").where(f3 > 0) + f1 = qb.Queryfield("subject") + f2 = qb.Queryfield("display_date") + f3 = qb.Queryfield("duration") + q = qb.select([f1, f2]).from_("calendar").where(f3 > 0) expected = "select subject, display_date from calendar where duration > 0" self.assertEqual(q, expected) return q def test_nearest_neighbor(self): - condition_uq = Q.userQuery() - condition_nn = Q.nearestNeighbor( + condition_uq = qb.userQuery() + condition_nn = qb.nearestNeighbor( field="dense_rep", query_vector="q_dense", annotations={"targetHits": 10} ) - q = ( - Query(select_fields=["id, text"]) - .from_("m") - .where(condition_uq | condition_nn) - ) + q = qb.select(["id, text"]).from_("m").where(condition_uq | condition_nn) expected = "select id, text from m where userQuery() or ({targetHits:10}nearestNeighbor(dense_rep, q_dense))" self.assertEqual(q, expected) return q @@ -133,7 +129,7 @@ def test_nearest_neighbor(self): def test_build_many_nn_operators(self): self.maxDiff = None conditions = [ - Q.nearestNeighbor( + qb.nearestNeighbor( field="colbert", query_vector=f"binary_vector_{i}", annotations={"targetHits": 100}, @@ -141,11 +137,7 @@ def test_build_many_nn_operators(self): for i in range(32) ] # Use Condition.any to combine conditions with OR - q = ( - Query(select_fields="*") - .from_("doc") - .where(condition=Condition.any(*conditions)) - ) + q = qb.select("*").from_("doc").where(condition=qb.any(*conditions)) expected = "select * from doc where " + " or ".join( [ f"({{targetHits:100}}nearestNeighbor(colbert, binary_vector_{i}))" @@ -156,48 +148,42 @@ def test_build_many_nn_operators(self): return q def test_field_comparison_operators(self): - f1 = Queryfield("age") + f1 = qb.Queryfield("age") condition = (f1 > 30) & (f1 <= 50) - q = Query(select_fields="*").from_("people").where(condition) + q = qb.select("*").from_("people").where(condition) expected = "select * from people where age > 30 and age <= 50" self.assertEqual(q, expected) return q def test_field_in_range(self): - f1 = Queryfield("age") + f1 = qb.Queryfield("age") condition = f1.in_range(18, 65) - q = Query(select_fields="*").from_("people").where(condition) + q = qb.select("*").from_("people").where(condition) expected = "select * from people where range(age, 18, 65)" self.assertEqual(q, expected) return q def test_field_annotation(self): - f1 = Queryfield("title") + f1 = qb.Queryfield("title") annotations = {"highlight": True} annotated_field = f1.annotate(annotations) - q = Query(select_fields="*").from_("articles").where(annotated_field) + q = qb.select("*").from_("articles").where(annotated_field) expected = "select * from articles where ({highlight:true})title" self.assertEqual(q, expected) return q def test_condition_annotation(self): - f1 = Queryfield("title") + f1 = qb.Queryfield("title") condition = f1.contains("Python") annotated_condition = condition.annotate({"filter": True}) - q = Query(select_fields="*").from_("articles").where(annotated_condition) + q = qb.select("*").from_("articles").where(annotated_condition) expected = 'select * from articles where {filter:true}title contains "Python"' self.assertEqual(q, expected) return q def test_grouping_with_condition(self): grouping = G.all(G.group("customer"), G.each(G.output(G.sum("price")))) - q = ( - Query(select_fields="*") - .from_("purchase") - .where(True) - .set_limit(0) - .groupby(grouping) - ) + q = qb.select("*").from_("purchase").where(True).set_limit(0).groupby(grouping) expected = "select * from purchase where true limit 0 | all(group(customer) each(output(sum(price))))" self.assertEqual(q, expected) return q @@ -211,7 +197,7 @@ def test_grouping_with_ordering_and_limiting(self): G.order(-G.count()), G.each(G.output(G.sum("price"))), ) - q = Query(select_fields="*").from_("purchase").where(True).groupby(grouping) + q = qb.select("*").from_("purchase").where(True).groupby(grouping) expected = "select * from purchase where true | all(group(customer) max(2) precision(12) order(-count()) each(output(sum(price))))" self.assertEqual(q, expected) return q @@ -221,14 +207,14 @@ def test_grouping_with_map_keys(self): G.group("mymap.key"), G.each(G.group("mymap.value"), G.each(G.output(G.count()))), ) - q = Query(select_fields="*").from_("purchase").where(True).groupby(grouping) + q = qb.select("*").from_("purchase").where(True).groupby(grouping) expected = "select * from purchase where true | all(group(mymap.key) each(group(mymap.value) each(output(count()))))" self.assertEqual(q, expected) return q def test_group_by_year(self): grouping = G.all(G.group("time.year(a)"), G.each(G.output(G.count()))) - q = Query(select_fields="*").from_("purchase").where(True).groupby(grouping) + q = qb.select("*").from_("purchase").where(True).groupby(grouping) expected = "select * from purchase where true | all(group(time.year(a)) each(output(count())))" self.assertEqual(q, expected) return q @@ -256,7 +242,7 @@ def test_grouping_with_date_agg(self): ), ), ) - q = Query(select_fields="*").from_("purchase").where(True).groupby(grouping) + q = qb.select("*").from_("purchase").where(True).groupby(grouping) expected = "select * from purchase where true | all(group(time.year(a)) each(output(count()) all(group(time.monthofyear(a)) each(output(count()) all(group(time.dayofmonth(a)) each(output(count()) all(group(time.hourofday(a)) each(output(count())))))))))" # q select * from purchase where true | all(group(time.year(a)) each(output(count()) all(group(time.monthofyear(a)) each(output(count()) all(group(time.dayofmonth(a)) each(output(count()) all(group(time.hourofday(a)) each(output(count()))))))))) # e select * from purchase where true | all(group(time.year(a)) each(output(count() all(group(time.monthofyear(a)) each(output(count()) all(group(time.dayofmonth(a)) each(output(count()) all(group(time.hourofday(a)) each(output(count()))))))))) @@ -266,10 +252,10 @@ def test_grouping_with_date_agg(self): return q def test_add_parameter(self): - f1 = Queryfield("title") + f1 = qb.Queryfield("title") condition = f1.contains("Python") q = ( - Query(select_fields="*") + qb.select("*") .from_("articles") .where(condition) .add_parameter("tracelevel", 1) @@ -279,17 +265,17 @@ def test_add_parameter(self): return q def test_custom_ranking_expression(self): - condition = Q.rank( - Q.userQuery(), Q.dotProduct("embedding", {"feature1": 1, "feature2": 2}) + condition = qb.rank( + qb.userQuery(), qb.dotProduct("embedding", {"feature1": 1, "feature2": 2}) ) - q = Query(select_fields="*").from_("documents").where(condition) + q = qb.select("*").from_("documents").where(condition) expected = 'select * from documents where rank(userQuery(), dotProduct(embedding, {"feature1":1,"feature2":2}))' self.assertEqual(q, expected) return q def test_wand(self): - condition = Q.wand("keywords", {"apple": 10, "banana": 20}) - q = Query(select_fields="*").from_("fruits").where(condition) + condition = qb.wand("keywords", {"apple": 10, "banana": 20}) + q = qb.select("*").from_("fruits").where(condition) expected = ( 'select * from fruits where wand(keywords, {"apple":10, "banana":20})' ) @@ -297,20 +283,20 @@ def test_wand(self): return q def test_wand_numeric(self): - condition = Q.wand("description", [[11, 1], [37, 2]]) - q = Query(select_fields="*").from_("fruits").where(condition) + condition = qb.wand("description", [[11, 1], [37, 2]]) + q = qb.select("*").from_("fruits").where(condition) expected = "select * from fruits where wand(description, [[11, 1], [37, 2]])" self.assertEqual(q, expected) return q def test_wand_annotations(self): self.maxDiff = None - condition = Q.wand( + condition = qb.wand( "description", weights={"a": 1, "b": 2}, annotations={"scoreThreshold": 0.13, "targetHits": 7}, ) - q = Query(select_fields="*").from_("fruits").where(condition) + q = qb.select("*").from_("fruits").where(condition) expected = 'select * from fruits where ({scoreThreshold: 0.13, targetHits: 7}wand(description, {"a":1, "b":2}))' print(q) print(expected) @@ -318,29 +304,29 @@ def test_wand_annotations(self): return q def test_weakand(self): - condition1 = Queryfield("title").contains("Python") - condition2 = Queryfield("description").contains("Programming") - condition = Q.weakAnd( + condition1 = qb.Queryfield("title").contains("Python") + condition2 = qb.Queryfield("description").contains("Programming") + condition = qb.weakAnd( condition1, condition2, annotations={"targetNumHits": 100} ) - q = Query(select_fields="*").from_("articles").where(condition) + q = qb.select("*").from_("articles").where(condition) expected = 'select * from articles where ({"targetNumHits": 100}weakAnd(title contains "Python", description contains "Programming"))' self.assertEqual(q, expected) return q def test_geolocation(self): - condition = Q.geoLocation("location_field", 37.7749, -122.4194, "10km") - q = Query(select_fields="*").from_("places").where(condition) + condition = qb.geoLocation("location_field", 37.7749, -122.4194, "10km") + q = qb.select("*").from_("places").where(condition) expected = 'select * from places where geoLocation(location_field, 37.7749, -122.4194, "10km")' self.assertEqual(q, expected) return q def test_condition_all_any(self): - c1 = Queryfield("f1").contains("v1") - c2 = Queryfield("f2").contains("v2") - c3 = Queryfield("f3").contains("v3") - condition = Condition.all(c1, c2, Condition.any(c3, ~c1)) - q = Query(select_fields="*").from_("sd1").where(condition) + c1 = qb.Queryfield("f1").contains("v1") + c2 = qb.Queryfield("f2").contains("v2") + c3 = qb.Queryfield("f3").contains("v3") + condition = qb.all(c1, c2, qb.any(c3, ~c1)) + q = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where f1 contains "v1" and f2 contains "v2" and (f3 contains "v3" or !(f1 contains "v1"))' self.assertEqual(q, expected) return q @@ -349,12 +335,7 @@ def test_order_by_with_annotations(self): f1 = "relevance" f2 = "price" annotations = {"strength": 0.5} - q = ( - Query(select_fields="*") - .from_("products") - .orderByDesc(f1, annotations) - .orderByAsc(f2) - ) + q = qb.select("*").from_("products").orderByDesc(f1, annotations).orderByAsc(f2) expected = ( 'select * from products order by {"strength":0.5}relevance desc, price asc' ) @@ -362,64 +343,64 @@ def test_order_by_with_annotations(self): return q def test_field_comparison_methods_builtins(self): - f1 = Queryfield("age") + f1 = qb.Queryfield("age") condition = (f1 >= 18) & (f1 < 30) - q = Query(select_fields="*").from_("users").where(condition) + q = qb.select("*").from_("users").where(condition) expected = "select * from users where age >= 18 and age < 30" self.assertEqual(q, expected) return q def test_field_comparison_methods(self): - f1 = Queryfield("age") + f1 = qb.Queryfield("age") condition = (f1.ge(18) & f1.lt(30)) | f1.eq(40) - q = Query(select_fields="*").from_("users").where(condition) + q = qb.select("*").from_("users").where(condition) expected = "select * from users where (age >= 18 and age < 30) or age = 40" self.assertEqual(q, expected) return q def test_filter_annotation(self): - f1 = Queryfield("title") + f1 = qb.Queryfield("title") condition = f1.contains("Python").annotate({"filter": True}) - q = Query(select_fields="*").from_("articles").where(condition) + q = qb.select("*").from_("articles").where(condition) expected = 'select * from articles where {filter:true}title contains "Python"' self.assertEqual(q, expected) return q def test_non_empty(self): - condition = Q.nonEmpty(Queryfield("comments").eq("any_value")) - q = Query(select_fields="*").from_("posts").where(condition) + condition = qb.nonEmpty(qb.Queryfield("comments").eq("any_value")) + q = qb.select("*").from_("posts").where(condition) expected = 'select * from posts where nonEmpty(comments = "any_value")' self.assertEqual(q, expected) return q def test_dotproduct(self): - condition = Q.dotProduct("vector_field", {"feature1": 1, "feature2": 2}) - q = Query(select_fields="*").from_("vectors").where(condition) + condition = qb.dotProduct("vector_field", {"feature1": 1, "feature2": 2}) + q = qb.select("*").from_("vectors").where(condition) expected = 'select * from vectors where dotProduct(vector_field, {"feature1":1,"feature2":2})' self.assertEqual(q, expected) return q def test_in_range_string_values(self): - f1 = Queryfield("date") + f1 = qb.Queryfield("date") condition = f1.in_range("2021-01-01", "2021-12-31") - q = Query(select_fields="*").from_("events").where(condition) + q = qb.select("*").from_("events").where(condition) expected = "select * from events where range(date, 2021-01-01, 2021-12-31)" self.assertEqual(q, expected) return q def test_condition_inversion(self): - f1 = Queryfield("status") + f1 = qb.Queryfield("status") condition = ~f1.eq("inactive") - q = Query(select_fields="*").from_("users").where(condition) + q = qb.select("*").from_("users").where(condition) expected = 'select * from users where !(status = "inactive")' self.assertEqual(q, expected) return q def test_multiple_parameters(self): - f1 = Queryfield("title") + f1 = qb.Queryfield("title") condition = f1.contains("Python") q = ( - Query(select_fields="*") + qb.select("*") .from_("articles") .where(condition) .add_parameter("tracelevel", 1) @@ -436,203 +417,195 @@ def test_multiple_groupings(self): G.output(G.count()), G.each(G.group("subcategory"), G.output(G.summary())), ) - q = Query(select_fields="*").from_("products").groupby(grouping) + q = qb.select("*").from_("products").groupby(grouping) expected = "select * from products | all(group(category) max(10) output(count()) each(group(subcategory) output(summary())))" self.assertEqual(q, expected) return q def test_userquery_basic(self): - condition = Q.userQuery("search terms") - q = Query(select_fields="*").from_("documents").where(condition) + condition = qb.userQuery("search terms") + q = qb.select("*").from_("documents").where(condition) expected = 'select * from documents where userQuery("search terms")' self.assertEqual(q, expected) return q - def test_q_p_function(self): - condition = Q.p( - Queryfield("f1").contains("v1"), - Queryfield("f2").contains("v2"), - Queryfield("f3").contains("v3"), - ) - q = Query(select_fields="*").from_("sd1").where(condition) - expected = 'select * from sd1 where f1 contains "v1" and f2 contains "v2" and f3 contains "v3"' - self.assertEqual(q, expected) - def test_rank_multiple_conditions(self): - condition = Q.rank( - Q.userQuery(), - Q.dotProduct("embedding", {"feature1": 1}), - Q.weightedSet("tags", {"tag1": 2}), + condition = qb.rank( + qb.userQuery(), + qb.dotProduct("embedding", {"feature1": 1}), + qb.weightedSet("tags", {"tag1": 2}), ) - q = Query(select_fields="*").from_("documents").where(condition) + q = qb.select("*").from_("documents").where(condition) expected = 'select * from documents where rank(userQuery(), dotProduct(embedding, {"feature1":1}), weightedSet(tags, {"tag1":2}))' self.assertEqual(q, expected) return q def test_non_empty_with_annotations(self): - annotated_field = Queryfield("comments").annotate({"filter": True}) - condition = Q.nonEmpty(annotated_field) - q = Query(select_fields="*").from_("posts").where(condition) + annotated_field = qb.Queryfield("comments").annotate({"filter": True}) + condition = qb.nonEmpty(annotated_field) + q = qb.select("*").from_("posts").where(condition) expected = "select * from posts where nonEmpty(({filter:true})comments)" self.assertEqual(q, expected) return q def test_weight_annotation(self): - condition = Queryfield("title").contains("heads", annotations={"weight": 200}) - q = Query(select_fields="*").from_("s1").where(condition) + condition = qb.Queryfield("title").contains( + "heads", annotations={"weight": 200} + ) + q = qb.select("*").from_("s1").where(condition) expected = 'select * from s1 where title contains({weight:200}"heads")' self.assertEqual(q, expected) return q def test_nearest_neighbor_annotations(self): - condition = Q.nearestNeighbor( + condition = qb.nearestNeighbor( field="dense_rep", query_vector="q_dense", annotations={"targetHits": 10} ) - q = Query(select_fields=["id, text"]).from_("m").where(condition) + q = qb.select(["id, text"]).from_("m").where(condition) expected = "select id, text from m where ({targetHits:10}nearestNeighbor(dense_rep, q_dense))" self.assertEqual(q, expected) return q def test_phrase(self): - text = Queryfield("text") - condition = text.contains(Q.phrase("st", "louis", "blues")) - query = Q.select("*").where(condition) + text = qb.Queryfield("text") + condition = text.contains(qb.phrase("st", "louis", "blues")) + query = qb.select("*").where(condition) expected = 'select * from * where text contains phrase("st", "louis", "blues")' self.assertEqual(query, expected) return query def test_near(self): - title = Queryfield("title") - condition = title.contains(Q.near("madonna", "saint")) - query = Q.select("*").where(condition) + title = qb.Queryfield("title") + condition = title.contains(qb.near("madonna", "saint")) + query = qb.select("*").where(condition) expected = 'select * from * where title contains near("madonna", "saint")' self.assertEqual(query, expected) return query def test_near_with_distance(self): - title = Queryfield("title") - condition = title.contains(Q.near("madonna", "saint", distance=10)) - query = Q.select("*").where(condition) + title = qb.Queryfield("title") + condition = title.contains(qb.near("madonna", "saint", distance=10)) + query = qb.select("*").where(condition) expected = 'select * from * where title contains ({distance:10}near("madonna", "saint"))' self.assertEqual(query, expected) return query def test_onear(self): - title = Queryfield("title") - condition = title.contains(Q.onear("madonna", "saint")) - query = Q.select("*").where(condition) + title = qb.Queryfield("title") + condition = title.contains(qb.onear("madonna", "saint")) + query = qb.select("*").where(condition) expected = 'select * from * where title contains onear("madonna", "saint")' self.assertEqual(query, expected) return query def test_onear_with_distance(self): - title = Queryfield("title") - condition = title.contains(Q.onear("madonna", "saint", distance=5)) - query = Q.select("*").where(condition) + title = qb.Queryfield("title") + condition = title.contains(qb.onear("madonna", "saint", distance=5)) + query = qb.select("*").where(condition) expected = 'select * from * where title contains ({distance:5}onear("madonna", "saint"))' self.assertEqual(query, expected) return query def test_same_element(self): - persons = Queryfield("persons") - first_name = Queryfield("first_name") - last_name = Queryfield("last_name") - year_of_birth = Queryfield("year_of_birth") + persons = qb.Queryfield("persons") + first_name = qb.Queryfield("first_name") + last_name = qb.Queryfield("last_name") + year_of_birth = qb.Queryfield("year_of_birth") condition = persons.contains( - Q.sameElement( + qb.sameElement( first_name.contains("Joe"), last_name.contains("Smith"), year_of_birth < 1940, ) ) - query = Q.select("*").from_("sd1").where(condition) + query = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where persons contains sameElement(first_name contains "Joe", last_name contains "Smith", year_of_birth < 1940)' self.assertEqual(query, expected) return query def test_equiv(self): - fieldName = Queryfield("fieldName") - condition = fieldName.contains(Q.equiv("A", "B")) - query = Q.select("*").where(condition) + fieldName = qb.Queryfield("fieldName") + condition = fieldName.contains(qb.equiv("A", "B")) + query = qb.select("*").where(condition) expected = 'select * from * where fieldName contains equiv("A", "B")' self.assertEqual(query, expected) return query def test_uri(self): - myUrlField = Queryfield("myUrlField") - condition = myUrlField.contains(Q.uri("vespa.ai/foo")) - query = Q.select("*").from_("sd1").where(condition) + myUrlField = qb.Queryfield("myUrlField") + condition = myUrlField.contains(qb.uri("vespa.ai/foo")) + query = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where myUrlField contains uri("vespa.ai/foo")' self.assertEqual(query, expected) return query def test_fuzzy(self): - myStringAttribute = Queryfield("f1") + myStringAttribute = qb.Queryfield("f1") annotations = {"prefixLength": 1, "maxEditDistance": 2} condition = myStringAttribute.contains( - Q.fuzzy("parantesis", annotations=annotations) + qb.fuzzy("parantesis", annotations=annotations) ) - query = Q.select("*").from_("sd1").where(condition) + query = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where f1 contains ({prefixLength:1,maxEditDistance:2}fuzzy("parantesis"))' self.assertEqual(query, expected) return query def test_userinput(self): - condition = Q.userInput("@myvar") - query = Q.select("*").from_("sd1").where(condition) + condition = qb.userInput("@myvar") + query = qb.select("*").from_("sd1").where(condition) expected = "select * from sd1 where userInput(@myvar)" self.assertEqual(query, expected) return query def test_userinput_param(self): - condition = Q.userInput("@animal") - query = Q.select("*").from_("sd1").where(condition).param("animal", "panda") + condition = qb.userInput("@animal") + query = qb.select("*").from_("sd1").where(condition).param("animal", "panda") expected = "select * from sd1 where userInput(@animal)&animal=panda" self.assertEqual(query, expected) return query def test_userinput_with_defaultindex(self): - condition = Q.userInput("@myvar").annotate({"defaultIndex": "text"}) - query = Q.select("*").from_("sd1").where(condition) + condition = qb.userInput("@myvar").annotate({"defaultIndex": "text"}) + query = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where {defaultIndex:"text"}userInput(@myvar)' self.assertEqual(query, expected) return query def test_in_operator_intfield(self): - integer_field = Queryfield("age") + integer_field = qb.Queryfield("age") condition = integer_field.in_(10, 20, 30) - query = Q.select("*").from_("sd1").where(condition) + query = qb.select("*").from_("sd1").where(condition) expected = "select * from sd1 where age in (10, 20, 30)" self.assertEqual(query, expected) return query def test_in_operator_stringfield(self): - string_field = Queryfield("status") + string_field = qb.Queryfield("status") condition = string_field.in_("active", "inactive") - query = Q.select("*").from_("sd1").where(condition) + query = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where status in ("active", "inactive")' self.assertEqual(query, expected) return query def test_predicate(self): - condition = Q.predicate( + condition = qb.predicate( "predicate_field", attributes={"gender": "Female"}, range_attributes={"age": "20L"}, ) - query = Q.select("*").from_("sd1").where(condition) + query = qb.select("*").from_("sd1").where(condition) expected = 'select * from sd1 where predicate(predicate_field,{"gender":"Female"},{"age":20L})' self.assertEqual(query, expected) return query def test_true(self): - query = Q.select("*").from_("sd1").where(True) + query = qb.select("*").from_("sd1").where(True) expected = "select * from sd1 where true" self.assertEqual(query, expected) return query def test_false(self): - query = Q.select("*").from_("sd1").where(False) + query = qb.select("*").from_("sd1").where(False) expected = "select * from sd1 where false" self.assertEqual(query, expected) return query diff --git a/vespa/querybuilder/builder/builder.py b/vespa/querybuilder/builder/builder.py index de92f382..527603fa 100644 --- a/vespa/querybuilder/builder/builder.py +++ b/vespa/querybuilder/builder/builder.py @@ -30,6 +30,10 @@ def __and__(self, other: Any) -> "Condition": def __or__(self, other: Any) -> "Condition": return Condition(f"{self.name} or {self._format_value(other)}") + # repr as str + def __repr__(self) -> str: + return self.name + def contains( self, value: Any, annotations: Optional[Dict[str, Any]] = None ) -> "Condition": @@ -317,18 +321,16 @@ def build(self, prepend_yql=False) -> str: class Q: @staticmethod - def select(*fields): - return Query(select_fields=list(fields)) + def select(fields): + return Query(select_fields=fields) @staticmethod - def p(*args): - if not args: - return Condition("") - else: - condition = args[0] - for arg in args[1:]: - condition = condition & arg - return condition + def any(*conditions): + return Condition.any(*conditions) + + @staticmethod + def all(*conditions): + return Condition.all(*conditions) @staticmethod def userQuery(value: str = "") -> Condition: