diff --git a/src/documents/search/_backend.py b/src/documents/search/_backend.py index d6a1ad41e..6dc920fdc 100644 --- a/src/documents/search/_backend.py +++ b/src/documents/search/_backend.py @@ -22,6 +22,7 @@ from guardian.shortcuts import get_users_with_perms from documents.search._query import build_permission_filter from documents.search._query import parse_simple_text_query +from documents.search._query import parse_simple_title_query from documents.search._query import parse_user_query from documents.search._schema import _write_sentinels from documents.search._schema import build_schema @@ -50,6 +51,7 @@ T = TypeVar("T") class SearchMode(StrEnum): QUERY = "query" TEXT = "text" + TITLE = "title" def _ascii_fold(s: str) -> str: @@ -460,7 +462,8 @@ class TantivyBackend: sort_field: Field to sort by (None for relevance ranking) sort_reverse: Whether to reverse the sort order search_mode: "query" for advanced Tantivy syntax, "text" for - plain-text search over title and content only + plain-text search over title and content only, "title" for + plain-text search over title only Returns: SearchResults with hits, total count, and processed query @@ -469,6 +472,8 @@ class TantivyBackend: tz = get_current_timezone() if search_mode is SearchMode.TEXT: user_query = parse_simple_text_query(self._index, query) + elif search_mode is SearchMode.TITLE: + user_query = parse_simple_title_query(self._index, query) else: user_query = parse_user_query(self._index, query, tz) diff --git a/src/documents/search/_query.py b/src/documents/search/_query.py index 6dbf78ca6..320315de8 100644 --- a/src/documents/search/_query.py +++ b/src/documents/search/_query.py @@ -438,6 +438,7 @@ DEFAULT_SEARCH_FIELDS = [ "tag", ] SIMPLE_SEARCH_FIELDS = ["title", "content"] +TITLE_SEARCH_FIELDS = ["title"] _FIELD_BOOSTS = {"title": 2.0} @@ -499,12 +500,13 @@ def parse_user_query( return exact -def parse_simple_text_query( +def parse_simple_query( index: tantivy.Index, raw_query: str, + fields: list[str], ) -> tantivy.Query: """ - Parse a plain-text query using Tantivy's default parser over title/content. + Parse a plain-text query using Tantivy over a restricted field set. Query string is escaped and normalized to be treated as "simple" text query. """ @@ -519,6 +521,28 @@ def parse_simple_text_query( query_str = regex.sub(r" {2,}", " ", query_str, timeout=_REGEX_TIMEOUT).strip() return index.parse_query( query_str, - SIMPLE_SEARCH_FIELDS, + fields, field_boosts=_FIELD_BOOSTS, ) + + +def parse_simple_text_query( + index: tantivy.Index, + raw_query: str, +) -> tantivy.Query: + """ + Parse a plain-text query over title/content for simple search inputs. + """ + + return parse_simple_query(index, raw_query, SIMPLE_SEARCH_FIELDS) + + +def parse_simple_title_query( + index: tantivy.Index, + raw_query: str, +) -> tantivy.Query: + """ + Parse a plain-text query over the title field only. + """ + + return parse_simple_query(index, raw_query, TITLE_SEARCH_FIELDS)