Extend free-text search (q) to also match payload
All checks were successful
Build and Deploy iObj / build-image (push) Successful in 36s
All checks were successful
Build and Deploy iObj / build-image (push) Successful in 36s
Cross-shard search already worked transparently across all monthly JSON files. This adds payload content (e.g. commit SHA, meeting attendees, structured data) to the q= substring match, alongside title and body.
This commit is contained in:
@@ -57,7 +57,7 @@ Alle `/objects*` endpoints kræver `Authorization: Bearer <IOBJ_API_TOKEN>`
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| GET | `/health` | Liveness check |
|
| GET | `/health` | Liveness check |
|
||||||
| POST | `/objects` | Opret objekt |
|
| POST | `/objects` | Opret objekt |
|
||||||
| GET | `/objects` | Søg (query params: `type`, `project`, `tag`, `date_from`, `date_to`, `q`, `limit`, `offset`) |
|
| GET | `/objects` | Søg (query params: `type`, `project`, `tag`, `date_from`, `date_to`, `q`, `limit`, `offset`). `q` matcher fritekst i `title`, `body` og `payload`. |
|
||||||
| GET | `/objects/date/{date}` | Alle objekter for én dato |
|
| GET | `/objects/date/{date}` | Alle objekter for én dato |
|
||||||
| GET | `/objects/{id}` | Hent ét objekt |
|
| GET | `/objects/{id}` | Hent ét objekt |
|
||||||
| PATCH | `/objects/{id}` | Opdater (delvist) |
|
| PATCH | `/objects/{id}` | Opdater (delvist) |
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ possibly contain matches for a given date range.
|
|||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
import re
|
import re
|
||||||
import threading
|
import threading
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
@@ -172,7 +173,8 @@ def _matches(obj: MemoryObject, query: SearchQuery) -> bool:
|
|||||||
return False
|
return False
|
||||||
if query.q:
|
if query.q:
|
||||||
needle = query.q.lower()
|
needle = query.q.lower()
|
||||||
haystack = f"{obj.title}\n{obj.body}".lower()
|
payload_text = json.dumps(obj.payload, ensure_ascii=False, default=str) if obj.payload else ""
|
||||||
|
haystack = f"{obj.title}\n{obj.body}\n{payload_text}".lower()
|
||||||
if needle not in haystack:
|
if needle not in haystack:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -119,6 +119,18 @@ def test_search_free_text_matches_title_and_body(store):
|
|||||||
assert len(results) == 2
|
assert len(results) == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_search_free_text_matches_payload(store):
|
||||||
|
store.create(_mk(title="commit", payload={"sha": "abc123def", "author": "Henrik Jess"}))
|
||||||
|
store.create(_mk(title="other commit", payload={"sha": "zzz999", "author": "Someone Else"}))
|
||||||
|
results = store.search(SearchQuery(q="abc123def"))
|
||||||
|
assert len(results) == 1
|
||||||
|
assert results[0].title == "commit"
|
||||||
|
|
||||||
|
results = store.search(SearchQuery(q="henrik"))
|
||||||
|
assert len(results) == 1
|
||||||
|
assert results[0].title == "commit"
|
||||||
|
|
||||||
|
|
||||||
def test_search_respects_limit_and_offset_and_sort_order(store):
|
def test_search_respects_limit_and_offset_and_sort_order(store):
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
store.create(_mk(object_date=date(2026, 1, 1 + i), title=f"obj{i}"))
|
store.create(_mk(object_date=date(2026, 1, 1 + i), title=f"obj{i}"))
|
||||||
|
|||||||
Reference in New Issue
Block a user