Translator
Translators convert between:
Generic query syntax used in internal logic, and
Specific query syntax required by a given search engine (e.g., PubMed, EBSCO, Web of Science).
Each translator implements QueryTranslator, the abstract base class from translator_base.py
.
Translator Responsibilities
A translator must implement the following two class methods:
to_generic_syntax(query, *, search_field_general) -> Query
to_specific_syntax(query) -> Query
Each method receives a Query object (the internal AST) and must return a new Query object with appropriately translated search fields and structure.
Utility Methods Provided
From the base class (QueryTranslator), you can use:
move_field_from_operator_to_terms(query)
: Moves a shared search field from the operator level to each child query.flatten_nested_operators(query)
: Merges nested logical operators of the same type into a flat structure.move_fields_to_operator(query)
: If all children have the same field, moves it to the parent node.
Search Field Mapping
Field mapping is expected to be defined in a constants_<source>.py file and typically includes:
syntax_str_to_generic_search_field_set()
: maps specific syntax string (e.g., TI, AB) to set of generic `Fields`. When the set contains multiple elements, the query must be extended with OR (see PubMed translator:_expand_combined_fields()
).generic_search_field_to_syntax_field()
: maps generic Fields to platform-specific syntax (set of fields). When combined fields are available, the query must be adapted before (see PubMed tranlsator:_combine_tiab()
).
Each translator should:
Translate fields in both directions
Handle combined fields (e.g., [tiab] in PubMed)
Optionally restructure the query for consistency
Code Skeleton
from search_query.constants_example import generic_search_field_set_to_syntax_set
from search_query.constants_example import map_search_field
from search_query.query import Query
from search_query.translator_base import QueryTranslator
class CustomTranslator(QueryTranslator):
"""Translator for Custom queries."""
@classmethod
def to_generic_syntax(cls, query: Query, *, search_field_general: str) -> Query:
query = query.copy()
cls.translate_search_fields_to_generic(query)
return query
@classmethod
def to_specific_syntax(cls, query: Query) -> Query:
query = query.copy()
cls._translate_search_fields(query)
return query
@classmethod
def translate_search_fields_to_generic(cls, query: Query) -> None:
if query.search_field:
fields = map_search_field(query.search_field.value)
if len(fields) == 1:
query.search_field.value = fields.pop()
else:
raise NotImplementedError
for child in query.children:
cls.translate_search_fields_to_generic(child)
@classmethod
def _translate_search_fields(cls, query: Query) -> None:
if query.search_field:
specific = generic_search_field_to_syntax_field(query.search_field.value)
query.search_field.value = specific
for child in query.children:
cls._translate_search_fields(child)
Advanced Features
Some translators include advanced restructuring logic:
PubMed: supports [tiab] expansion into OR combinations of [ti] and [ab]