Skip to content

Search

Source code in ftmq/search/store/__init__.py
@cache
def get_store(**kwargs: Any) -> BaseStore:
    settings = Settings()
    uri = kwargs.pop("uri", None)
    if uri is None:
        if settings.yaml_uri is not None:
            store = BaseStore.from_yaml_uri(settings.yaml_uri, **kwargs)
            return get_store(**store.model_dump())
        if settings.json_uri is not None:
            store = BaseStore.from_json_uri(settings.json_uri, **kwargs)
            return get_store(**store.model_dump())
        uri = settings.uri
    uri = ensure_uri(uri)
    parsed = urlparse(uri)
    if parsed.scheme == "sqlite":
        return SQliteStore(uri=uri, **kwargs)
    if parsed.scheme in ("tantivy", "memory"):
        try:
            from ftmq.search.store.tantivy import TantivyStore

            return TantivyStore(uri=uri, memory=parsed.scheme == "memory")
        except ImportError as e:
            raise ImportError(
                "Can not load TantivyStore. Install `tantivy` (`ftmq[search]`)"
            ) from e
    raise NotImplementedError(f"Store scheme: `{parsed.scheme}`")

FilterTerm dataclass

One search-index predicate: field holds any of values - or none of them, if negated. The terms of a query AND together.

Source code in ftmq/search/store/base.py
@dataclass(frozen=True)
class FilterTerm:
    """One search-index predicate: `field` holds any of `values` - or none of
    them, if `negated`. The terms of a query AND together."""

    field: str
    values: frozenset[str]
    negated: bool = False

get_filters(query)

Compile a query's filter tree into the flat term list a search index can apply.

The index holds three filterable fields (datasets, schema, countries); a filter on anything else is dropped. A not / not_in comparator (or a ~ around a single condition) becomes a negated term instead of being read as a positive one, and a shape that cannot be expressed as ANDed terms - a cross-field OR, a negated group, a comparator like ilike on an indexed field - raises.

Parameters:

Name Type Description Default
query Query | None

The query to compile (None means no filters).

required

Returns:

Type Description
list[FilterTerm]

The terms to AND together.

Raises:

Type Description
QueryError

If the query's filter tree is not expressible.

Source code in ftmq/search/store/base.py
def get_filters(query: Query | None) -> list[FilterTerm]:
    """Compile a query's filter tree into the flat term list a search index can
    apply.

    The index holds three filterable fields (`datasets`, `schema`,
    `countries`); a filter on anything else is dropped. A `not` / `not_in`
    comparator (or a `~` around a single condition) becomes a negated term
    instead of being read as a positive one, and a shape that cannot be
    expressed as ANDed terms - a cross-field OR, a negated group, a comparator
    like `ilike` on an indexed field - raises.

    Args:
        query: The query to compile (`None` means no filters).

    Returns:
        The terms to AND together.

    Raises:
        QueryError: If the query's filter tree is not expressible.
    """
    if query is None or query.q is None:
        return []
    return _collect(query.q)