Skip to content

Commit 2dd50b6

Browse files
authored
Merge branch 'main' into auth/allow-string-api-key-in-connect-helpers
2 parents 6c172b0 + 4c3b939 commit 2dd50b6

13 files changed

Lines changed: 167 additions & 39 deletions

File tree

docs/changelog.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
Changelog
22
=========
33

4+
Version 4.14.3
5+
--------------
6+
This patch version includes:
7+
- Fixes return type for aggregate with group_by and zero results
8+
- Fix multi-vector with hybrid search
9+
10+
Version 4.14.2
11+
--------------
12+
not released
13+
414
Version 4.14.1
515
--------------
616
This patch version includes:

integration/test_collection_aggregate.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ def test_aggregation_groupby_with_limit(collection_factory: CollectionFactory) -
9999
assert res.groups[1].properties["text"].count == 1
100100

101101

102+
def test_aggregation_groupby_no_results(collection_factory: CollectionFactory) -> None:
103+
collection = collection_factory(properties=[Property(name="text", data_type=DataType.TEXT)])
104+
res = collection.aggregate.over_all(
105+
return_metrics=[Metrics("text").text(count=True)],
106+
group_by=GroupByAggregate(prop="text", limit=2),
107+
)
108+
assert len(res.groups) == 0
109+
110+
102111
@pytest.mark.parametrize(
103112
"filter_",
104113
[

integration/test_collection_nested.py

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -516,34 +516,77 @@ def test_nested_return_specific_properties(
516516
assert out.properties["nested"] == expected
517517

518518

519-
def test_nested_return_generic_properties(collection_factory: CollectionFactory) -> None:
520-
class Child(TypedDict):
521-
name: str
522-
age: int
519+
class Child(TypedDict):
520+
name: str
521+
age: int
523522

524-
class Parent(TypedDict):
525-
child: Nested[Child]
526523

527-
collection = collection_factory(
528-
properties=[
529-
Property(
530-
name="child",
531-
data_type=DataType.OBJECT,
532-
nested_properties=[
533-
Property(
534-
name="name",
535-
data_type=DataType.TEXT,
536-
),
537-
Property(
538-
name="age",
539-
data_type=DataType.INT,
540-
),
524+
@pytest.mark.parametrize(
525+
"data_model_cls,data_object,properties",
526+
[
527+
(
528+
Child,
529+
{"name": "Timmy", "age": 10},
530+
[
531+
Property(name="name", data_type=DataType.TEXT),
532+
Property(name="age", data_type=DataType.INT),
533+
],
534+
),
535+
(
536+
TypedDict("ParentWithChild", {"name": str, "age": int, "child": Nested[Child]}),
537+
{
538+
"name": "Bob",
539+
"age": 39,
540+
"child": {"name": "Timmy", "age": 10},
541+
},
542+
[
543+
Property(name="name", data_type=DataType.TEXT),
544+
Property(name="age", data_type=DataType.INT),
545+
Property(
546+
name="child",
547+
data_type=DataType.OBJECT,
548+
nested_properties=[
549+
Property(name="name", data_type=DataType.TEXT),
550+
Property(name="age", data_type=DataType.INT),
551+
],
552+
),
553+
],
554+
),
555+
(
556+
TypedDict(
557+
"ParentWithChildList", {"name": str, "age": int, "children": Nested[list[Child]]}
558+
),
559+
{
560+
"name": "Bob",
561+
"age": 39,
562+
"children": [
563+
{"name": "Timmy", "age": 10},
564+
{"name": "Daisy", "age": 8},
541565
],
542-
)
543-
],
544-
data_model_properties=Parent,
566+
},
567+
[
568+
Property(name="name", data_type=DataType.TEXT),
569+
Property(name="age", data_type=DataType.INT),
570+
Property(
571+
name="children",
572+
data_type=DataType.OBJECT_ARRAY,
573+
nested_properties=[
574+
Property(name="name", data_type=DataType.TEXT),
575+
Property(name="age", data_type=DataType.INT),
576+
],
577+
),
578+
],
579+
),
580+
],
581+
)
582+
def test_nested_return_generic_properties(
583+
collection_factory, data_model_cls, data_object, properties
584+
):
585+
collection = collection_factory(
586+
properties=properties,
587+
data_model_properties=data_model_cls,
545588
)
589+
collection.data.insert(data_object)
590+
results = collection.query.fetch_objects(return_properties=data_model_cls)
546591

547-
collection.data.insert(Parent(child=Child(name="Timmy", age=10)))
548-
results = collection.query.fetch_objects(return_properties=Parent)
549-
assert results.objects[0].properties["child"] == {"name": "Timmy", "age": 10}
592+
assert results.objects[0].properties == data_object

integration/test_named_vectors.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,20 @@ def test_colbert_vectors_byov(collection_factory: CollectionFactory) -> None:
835835
).objects
836836
assert len(objs) == 1
837837

838+
objs = collection.query.hybrid(
839+
None,
840+
vector=[1, 2],
841+
target_vector="regular",
842+
).objects
843+
assert len(objs) == 1
844+
845+
objs = collection.query.hybrid(
846+
None,
847+
vector=[[1, 2], [3, 4]],
848+
target_vector="colbert",
849+
).objects
850+
assert len(objs) == 1
851+
838852
objs = collection.query.hybrid(
839853
None,
840854
vector={"colbert": [[1, 2], [3, 4]]},

weaviate/collections/aggregations/base_executor.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,17 @@ def _to_aggregate_result(
9292
)
9393

9494
def _to_result(
95-
self, response: aggregate_pb2.AggregateReply
95+
self, is_groupby: bool, response: aggregate_pb2.AggregateReply
9696
) -> Union[AggregateReturn, AggregateGroupByReturn]:
97-
if response.HasField("single_result"):
97+
if not is_groupby:
9898
return AggregateReturn(
9999
properties={
100100
aggregation.property: self.__parse_property_grpc(aggregation)
101101
for aggregation in response.single_result.aggregations.aggregations
102102
},
103103
total_count=response.single_result.objects_count,
104104
)
105-
if response.HasField("grouped_results"):
105+
if is_groupby:
106106
return AggregateGroupByReturn(
107107
groups=[
108108
AggregateGroup(
@@ -116,9 +116,6 @@ def _to_result(
116116
for group in response.grouped_results.groups
117117
]
118118
)
119-
else:
120-
_Warnings.unknown_type_encountered(response.WhichOneof("result"))
121-
return AggregateReturn(properties={}, total_count=None)
122119

123120
def __parse_grouped_by_value(
124121
self, grouped_by: aggregate_pb2.AggregateReply.Group.GroupedBy

weaviate/collections/aggregations/hybrid/executor.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from weaviate.connect import executor
1313
from weaviate.connect.v4 import ConnectionType
1414
from weaviate.exceptions import WeaviateUnsupportedFeatureError
15+
from weaviate.proto.v1 import aggregate_pb2
1516
from weaviate.types import NUMBER
1617

1718

@@ -161,8 +162,14 @@ def resp(res: dict) -> Union[AggregateReturn, AggregateGroupByReturn]:
161162
limit=group_by.limit if group_by is not None else None,
162163
objects_count=total_count,
163164
)
165+
166+
def respGrpc(
167+
res: aggregate_pb2.AggregateReply,
168+
) -> Union[AggregateReturn, AggregateGroupByReturn]:
169+
return self._to_result(group_by is not None, res)
170+
164171
return executor.execute(
165-
response_callback=self._to_result,
172+
response_callback=respGrpc,
166173
method=self._connection.grpc_aggregate,
167174
request=request,
168175
)

weaviate/collections/aggregations/near_image/executor.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from weaviate.collections.filters import _FilterToGRPC
1212
from weaviate.connect import executor
1313
from weaviate.connect.v4 import ConnectionType
14+
from weaviate.proto.v1 import aggregate_pb2
1415
from weaviate.types import BLOB_INPUT, NUMBER
1516
from weaviate.util import parse_blob
1617

@@ -144,8 +145,14 @@ def resp(res: dict) -> Union[AggregateReturn, AggregateGroupByReturn]:
144145
objects_count=total_count,
145146
object_limit=object_limit,
146147
)
148+
149+
def respGrpc(
150+
res: aggregate_pb2.AggregateReply,
151+
) -> Union[AggregateReturn, AggregateGroupByReturn]:
152+
return self._to_result(group_by is not None, res)
153+
147154
return executor.execute(
148-
response_callback=self._to_result,
155+
response_callback=respGrpc,
149156
method=self._connection.grpc_aggregate,
150157
request=request,
151158
)

weaviate/collections/aggregations/near_object/executor.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from weaviate.collections.filters import _FilterToGRPC
1212
from weaviate.connect import executor
1313
from weaviate.connect.v4 import ConnectionType
14+
from weaviate.proto.v1 import aggregate_pb2
1415
from weaviate.types import NUMBER, UUID
1516

1617

@@ -142,8 +143,14 @@ def resp(res: dict) -> Union[AggregateReturn, AggregateGroupByReturn]:
142143
objects_count=total_count,
143144
object_limit=object_limit,
144145
)
146+
147+
def respGrpc(
148+
res: aggregate_pb2.AggregateReply,
149+
) -> Union[AggregateReturn, AggregateGroupByReturn]:
150+
return self._to_result(group_by is not None, res)
151+
145152
return executor.execute(
146-
response_callback=self._to_result,
153+
response_callback=respGrpc,
147154
method=self._connection.grpc_aggregate,
148155
request=request,
149156
)

weaviate/collections/aggregations/near_text/executor.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from weaviate.collections.filters import _FilterToGRPC
1313
from weaviate.connect import executor
1414
from weaviate.connect.v4 import ConnectionType
15+
from weaviate.proto.v1 import aggregate_pb2
1516
from weaviate.types import NUMBER
1617

1718

@@ -162,8 +163,14 @@ def resp(res: dict) -> Union[AggregateReturn, AggregateGroupByReturn]:
162163
objects_count=total_count,
163164
object_limit=object_limit,
164165
)
166+
167+
def respGrpc(
168+
res: aggregate_pb2.AggregateReply,
169+
) -> Union[AggregateReturn, AggregateGroupByReturn]:
170+
return self._to_result(group_by is not None, res)
171+
165172
return executor.execute(
166-
response_callback=self._to_result,
173+
response_callback=respGrpc,
167174
method=self._connection.grpc_aggregate,
168175
request=request,
169176
)

weaviate/collections/aggregations/near_vector/executor.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from weaviate.connect import executor
1717
from weaviate.connect.v4 import ConnectionType
1818
from weaviate.exceptions import WeaviateInvalidInputError
19+
from weaviate.proto.v1 import aggregate_pb2
1920
from weaviate.types import NUMBER
2021

2122

@@ -163,8 +164,14 @@ def resp(res: dict) -> Union[AggregateReturn, AggregateGroupByReturn]:
163164
objects_count=total_count,
164165
object_limit=object_limit,
165166
)
167+
168+
def respGrpc(
169+
res: aggregate_pb2.AggregateReply,
170+
) -> Union[AggregateReturn, AggregateGroupByReturn]:
171+
return self._to_result(group_by is not None, res)
172+
166173
return executor.execute(
167-
response_callback=self._to_result,
174+
response_callback=respGrpc,
168175
method=self._connection.grpc_aggregate,
169176
request=request,
170177
)

0 commit comments

Comments
 (0)