Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

As said before Search API has normalization of parameters and responses, this allows us to make one piece of code making a search request to an connection of type we don't know, to a engine we don't care about, and be sure it will work. 

To ease the process of creating generic request, Search API has different classes with well defined parameters

SearchRequest

This request is one of the parameters expected by engine methods (search, multi_search, async_search and knn_search). SearchRequest holds all the possible parameters this methods could need, the implementation of this parameters depend on the engine specific implementation, and not all parameters are shared amongst all the methods

PropertyDescriptionDefaultTypeRequired
qQuery String"*"stringNo
queryAccepts the search query structure in the specific engine's format
objectNo
knnAccepts the knn search structure in the the specific engine's format
objectNo
rescoreThe query rescorer executes a second query only on the Top-K results returned. Expected in the specific engine's format
objectNo
sizeDefines the number of hits to return
integer (minimum: 0)No
startStarting document offset. Needs to be non-negative
integer (minimum: 0)No
scrollPeriod to retain the search context for scrolling
stringNo
sortEngine string definition or generic SortEntry defining the sort order
array of objectsNo
fetch_fieldsList of fields to return in the response based on field values
array of stringsNo
default_operatorThe default operator for the query string query: AND or OR"or"stringNo
highlightHighlighters enable you to get highlighted snippets from one or more fields in your search results so you can show users where the query matches are
objectNo
filtersTuple of engine-specific filters. The tuple must contain optional_negated_filters, optional_filters, required_negated_filters, required_filters
objectNo
agg_filtersTuple of engine-specific filters. The tuple must contain optional_negated_filters, optional_filters, required_negated_filters, required_filters
objectNo
aggsList of engine-specific aggregation implementations
objectNo
exclude_fieldsList of fields to exclude in the response based on field values
array of stringsNo


If you have a keen eye you notice several parameters are simple object types, opening up to a wide variety of options what it can receive, all this options are expecting engine specific format. This was done on purpose to allow the developer to tweak with the queries before sending them to the engine, to compensate for this non-agnostic approach Search API has agnostic tools

For Q, Query and KNN

For the string parameter q, one approach available is the use of PYQPL, this library can translate query string to engine specific queries, here an example

Code Block
languagepy
themeDJango
from app.rest import connection_manager
from pyqpl.parser import QPLParser
from pyqpl.qpl import QPLOptions
from pyqpl.translator import ElasticsearchTranslator, OpensearchTranslator
from models.engines import EngineTypes

# Get the conneciton_manager for access to the connection
from app.rest import connection_manager

# Get engine by name
engine = connection_manager.get_engine(name=engine_name)

# Based on the engine type, select the QPL Translator to use
if engine.engine_type is EngineTypes.ELASTIC:
    translator = ElasticsearchTranslator()
elif engine.engine_type is EngineTypes.OPENSEARCH:
    translator = OpensearchTranslator()

# Create the QPL parser based on the provided configuration
qpl_parser = QPLParser(options=qpl_config)

# Use the parser to parse the string in the parameter q
qpl_query = qpl_parser.parse_query(data=q)
# Use the translator to transforma the QPLQuery from the parser to an engine specific format
query = translator.to_engine_query(qpl_query)

This method allows you to have access to the QPLQuery, which can be manipulated (for information on this please check PYQPL space), and/or access to the engine specific query, and modify, inject or remove as desired.

For Highlight

Code Block
languagepy
themeDJango
from app.rest import connection_manager
from models.engines import EngineTypes
from models.engines import HighlightConfig

# Get the conneciton_manager for access to the connection
from app.rest import connection_manager

# Get engine by name
engine = connection_manager.get_engine(name=engine_name)


# Convert HighlightConfig to engine specific
engine_highlight = engine.generate_highlight(highlight_config) 


For Filters

Code Block
languagepy
themeDJango
from app.rest import connection_manager
from models.engines import EngineTypes
from models.engines import FilterConfig, SearchFilters
from framework.filters import DynamicFilter

# Get the conneciton_manager for access to the connection
from app.rest import connection_manager

# Get engine by name
engine = connection_manager.get_engine(name=engine_name)


# Convert a list of DynamicFilter to engine specific, in the SearchFilters container
engine_filters: SearchFilters = self.engine.generate_filters(list_of_filters)

# Additionally you can merge filters from different sources
engine_filters = SearchFilters.merge_filters(engine_filters, self.engine.generate_filters(filters_from_request))


For Aggregations

Code Block
languagepy
themeDJango
from app.rest import connection_manager
from models.engines import EngineTypes
from framework.aggregations import DynamicAgg
from framework.aggregations.utils import SelectionAgg

# Get the conneciton_manager for access to the connection
from app.rest import connection_manager

# Get engine by name
engine = connection_manager.get_engine(name=engine_name)


# Convert a list of DynamicAgg to engine specific aggregations
aggregations: Dict = engine.generate_aggregations(list_of_aggregations)

# To convert selected aggregations into filters
applied _filters = engine.generate_aggregation_filters(list_of_aggregations, list_of_selected_aggregations))
Code Block
# Define request, not all parameters are required
request: SearchRequest = SearchRequest(
            q=q,
            query=query,
            knn=knn,
            size=10,
            start=0,
            fetch_fields=['content', 'title'],
            exclude_fields=['date'], 
            scroll=None,
            sort=SortEntry(field='title', order=SortOrder.ASC),
            default_operator=BoolOperation.OR,
            highlight=highlight,
            filters=filters,
            agg_filters=agg_filters,
            aggs=aggs,
        )

# Execute a search with the engine
response = engine.search(index='my_index', data=request)       

# Verify response is not ErrorResponse
if isinstance(response, ErrorResponse):
    raise ConnectionError(f'Error {response.status_code}) {response.error}')

# Profit
return response

SortEntry

PropertyDescriptionTypeRequired
fieldName of the field which will be used for sortingstringYes
display_nameDisplay name for this sort entry. Only applicable for the user interfacestringNo
orderSort order to be used. It can be one of the predefined SortOrder values or a custom object with additional propertiesstring or objectYes

SortOrder

An enumeration.

ValueDescription
ascAscending sort order
descDescending sort order

SearchFilters

PropertyDescriptionDefaultTypeRequired
should_notFilter which will act as a boolean operator NOR[]array of objectsNo
shouldFilter which will act as a boolean operator OR[]array of objectsNo
must_notFilter which will act as a boolean operator NAND[]array of objectsNo
mustFilter which will act as a boolean operator AND[]array of objectsNo
post_should_notFilter which will act as a boolean operator NOR[]array of objectsNo
post_shouldFilter which will act as a boolean operator OR[]array of objectsNo
post_must_notFilter which will act as a boolean operator NAND[]array of objectsNo
post_mustFilter which will act as a boolean operator AND[]array of objectsNo