Skip to content

Commit

Permalink
Fix indexing on results after applying a search query (#586)
Browse files Browse the repository at this point in the history
* Fix indexing on results after aookyying a search query

* WIP: added clients based on map and catalog adapters using pytest.FixtureRequest

* Added test case for indexing and reorganized test_search to implement pytest.FixtureRequest
  • Loading branch information
jmaruland authored Oct 30, 2023
1 parent 188c005 commit d2064c4
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 20 deletions.
51 changes: 38 additions & 13 deletions tiled/_tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

from ..adapters.array import ArrayAdapter
from ..adapters.mapping import MapAdapter
from ..catalog import in_memory
from ..client import Context, from_context
from ..queries import FullText
from ..queries import FullText, Key
from ..server.app import build_app

tree = MapAdapter(
Expand All @@ -23,36 +24,60 @@


@pytest.fixture(scope="module")
def client():
def map_client():
app = build_app(tree)
with Context.from_app(app) as context:
client = from_context(context)
yield client


@pytest.fixture
def catalog_client(tmpdir):
catalog = in_memory(writable_storage=str(tmpdir))
app = build_app(catalog)
with Context.from_app(app) as context:
client = from_context(context)
# Upload arrays and metadata from tree into client so that it has matching content.
for key, value in tree.items():
client.write_array(value.read(), metadata=value.metadata(), key=key)
yield client


@pytest.fixture(
params=("map_client", "catalog_client"),
)
def client(request: pytest.FixtureRequest):
yield request.getfixturevalue(request.param)


@pytest.mark.parametrize(
"term, expected_keys",
"key, value, expected_keys",
[
("red", ["a"]),
("yellow", ["b"]),
("orange", ["c"]),
("dog", ["a", "b"]),
("cat", ["c"]),
("apple", "red", ["a"]),
("banana", "yellow", ["b"]),
("cantalope", "orange", ["c"]),
("animal", "dog", ["a", "b"]),
("animal", "cat", ["c"]),
],
)
def test_search(client, term, expected_keys):
query = FullText(term)
results = client.search(query)
def test_search(client, key, value, expected_keys):
query = Key(key)
results = client.search(query == value)
assert list(results) == expected_keys


def test_compound_search(client):
results = client.search(FullText("dog")).search(FullText("yellow"))
results = client.search(Key("animal") == "dog").search(Key("banana") == "yellow")
assert list(results) == ["b"]


def test_indexing_over_search(client):
results = client.search(Key("animal") == "dog")
assert dict(results["a"].metadata) == tree["a"].metadata()


def test_key_into_results(client):
results = client.search(FullText("dog"))
results = client.search(Key("animal") == "dog")
assert "apple" in results["a"].metadata
assert "banana" in results["b"].metadata
assert "c" not in results # This *is* in the tree but not among the results.
Expand Down
21 changes: 15 additions & 6 deletions tiled/server/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def pagination_links(base_url, route, path_parts, offset, limit, length_hint):
return links


def apply_search(tree, filters, query_registry):
async def apply_search(tree, filters, query_registry):
queries = defaultdict(
dict
) # e.g. {"text": {"text": "dog"}, "lookup": {"key": "..."}}
Expand Down Expand Up @@ -146,10 +146,19 @@ def apply_search(tree, filters, query_registry):
# Two non-equal KeyLookup queries must return no results.
tree = MapAdapter({})
else:
try:
tree = MapAdapter({key_lookup: tree[key_lookup]}, must_revalidate=False)
except KeyError:
tree = MapAdapter({})
if hasattr(tree, "lookup_adapter"):
entry = await tree.lookup_adapter([key_lookup])
if entry is None:
tree = MapAdapter({})
else:
tree = MapAdapter({key_lookup: entry}, must_revalidate=False)
else:
try:
tree = MapAdapter(
{key_lookup: tree[key_lookup]}, must_revalidate=False
)
except KeyError:
tree = MapAdapter({})

return tree

Expand Down Expand Up @@ -191,7 +200,7 @@ async def construct_entries_response(
max_depth,
):
path_parts = [segment for segment in path.split("/") if segment]
tree = apply_search(tree, filters, query_registry)
tree = await apply_search(tree, filters, query_registry)
tree = apply_sort(tree, sort)

count = await len_or_approx(tree)
Expand Down
2 changes: 1 addition & 1 deletion tiled/server/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ async def distinct(
**filters,
):
if hasattr(entry, "get_distinct"):
filtered = apply_search(entry, filters, query_registry)
filtered = await apply_search(entry, filters, query_registry)
distinct = await ensure_awaitable(
filtered.get_distinct, metadata, structure_families, specs, counts
)
Expand Down

0 comments on commit d2064c4

Please sign in to comment.