Skip to content

Commit

Permalink
feat: mvi id in set filter expression (#430)
Browse files Browse the repository at this point in the history
Bumps the python proto dependency and implements the MVI filter expression IdInSet. This filter expression is satisfied when an item has an id that is in the set provided by the user. We also add integration tests for this filter.
  • Loading branch information
malandis authored Feb 6, 2024
1 parent a754c1b commit 1295167
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 7 deletions.
20 changes: 16 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ exclude = ["src/momento/internal/codegen.py"]
[tool.poetry.dependencies]
python = "^3.7"

momento-wire-types = "^0.102.1"
momento-wire-types = "^0.105.1"
grpcio = "^1.46.0"
# note if you bump this presigned url test need be updated
pyjwt = "^2.4.0"
Expand Down
15 changes: 15 additions & 0 deletions src/momento/requests/vector_index/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Iterable

from momento_wire_types import vectorindex_pb2 as vectorindex_pb

Expand Down Expand Up @@ -258,3 +259,17 @@ def to_filter_expression_proto(self) -> vectorindex_pb._FilterExpression:
def to_proto(self) -> vectorindex_pb._ListContainsExpression:
# todo should make oneof defensively
return vectorindex_pb._ListContainsExpression(field=self.field, string_value=self.value)


@dataclass
class IdInSet(FilterExpression):
"""Represents an expression to test if an item id is in a set of ids."""

ids: Iterable[str]
"""The set of ids to test id in set with."""

def to_filter_expression_proto(self) -> vectorindex_pb._FilterExpression:
return vectorindex_pb._FilterExpression(id_in_set_expression=self.to_proto())

def to_proto(self) -> vectorindex_pb._IdInSetExpression:
return vectorindex_pb._IdInSetExpression(ids=list(self.ids))
5 changes: 4 additions & 1 deletion tests/momento/vector_index_client/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from momento import PreviewVectorIndexClient
from momento.common_data.vector_index.item import Metadata
from momento.errors import MomentoErrorCode
from momento.requests.vector_index import ALL_METADATA, Field, FilterExpression, Item, SimilarityMetric
from momento.requests.vector_index import ALL_METADATA, Field, FilterExpression, Item, SimilarityMetric, filters
from momento.responses.vector_index import (
CountItems,
CreateIndex,
Expand Down Expand Up @@ -657,6 +657,9 @@ def test_search_with_filter_expression(
["test_item_1", "test_item_2", "test_item_3"],
"list contains b or int > 1",
),
(filters.IdInSet({}), [], "id in empty set"),
(filters.IdInSet({"not there"}), [], "id in set not there"),
(filters.IdInSet({"test_item_1", "test_item_3"}), ["test_item_1", "test_item_3"], "id in set"),
]:
filter_expression = cast(FilterExpression, filter_expression)
search_response = vector_index_client.search(
Expand Down
5 changes: 4 additions & 1 deletion tests/momento/vector_index_client/test_data_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from momento import PreviewVectorIndexClientAsync
from momento.common_data.vector_index.item import Metadata
from momento.errors import MomentoErrorCode
from momento.requests.vector_index import ALL_METADATA, Field, FilterExpression, Item, SimilarityMetric
from momento.requests.vector_index import ALL_METADATA, Field, FilterExpression, Item, SimilarityMetric, filters
from momento.responses.vector_index import (
CountItems,
CreateIndex,
Expand Down Expand Up @@ -661,6 +661,9 @@ async def test_search_with_filter_expression(
["test_item_1", "test_item_2", "test_item_3"],
"list contains b or int > 1",
),
(filters.IdInSet({}), [], "id in empty set"),
(filters.IdInSet({"not there"}), [], "id in set not there"),
(filters.IdInSet({"test_item_1", "test_item_3"}), ["test_item_1", "test_item_3"], "id in set"),
]:
filter_expression = cast(FilterExpression, filter_expression)
search_response = await vector_index_client_async.search(
Expand Down

0 comments on commit 1295167

Please sign in to comment.