Skip to main content

Quickstart: Api frontend integration

The QSC provides a easy configuration of your Search-App with is accessible by an RESTful Api that enable full flexibility in search integration.

Preconditions: In this chapter we assume you have already configured your Search-App

Search Endpoint

The search endpoint supports GET POST requests. The GET API is for simple integrations and SEO use cases where the url parameter are relevant. For more complex integrations or SPA we recommend the POST API.

GET API

The Search Endpoint (Open Api Spec) is requested with the QuasiriS-Query-Language (QSQL) per GET, POST and return a search response with contains the found documents and all required informations for the frontend.

GET request parameters

ParametersExampleDescription
qq=fooQuery
f.idf.id=42Filter the id with default operator AND
f.id.orf.id.or=42&f.id.or=44Filter the id with operator OR
f.id.or[]f.id.or[]=42,44Filter the id with operator OR
f.id.andf.id.and=42&f.id.and=44Filter the id with operator AND
f.id.and[]f.id.or[]=42,44Filter the id with operator AND
f.id.notf.id.not=42&f.id.not=44Filter the id that not has the values
f.id.not[]f.id.not[]=42,44Filter the id that not has the values
f.price.rangef.id.rangeRange filter (Slider) for a configured slider-id
f.create.daterangef.crete.daterange=NOW,*Range filter for date value
f.create.daterangef.timestamp.daterange=2021-01-02T23:00:00Z,2021-02-05T20:59:38ZRange filter for date values
f.created.humandatef.created.humandate=last weekFilter for date values
sortsort=priceSort by price
pagepage=3Pagination - selected page first page is 1 (default)
rowsrows=12Pagination - Number of returned documents
ctrlctrl=facetDisabledControl parameter - a comma seperated list of parameters
ctrl=facetDisabledctrl=facetDisableddisable facets
ctrl=spellcheckDisabledctrl=spellcheckDisableddisable spellcheck
result.displayFieldsresult.displayFields=_score,idreturn the fields _score and id in the document result
result.displayFacetsresult.displayFacets=timestamp,created_datereturn the facets timestamp and created_date in the result

Multiple Filter Values

The API provides two ways to use multiple filter values:

  • multiple url parameters - f.id.or=42&f.id.or=44
  • array [] syntax with comma seperated values - f.id.or[]=42,44

Example Request:

Search for wago with filters available=true, category=Reihenklemmen where the documents are sorted by price descending shown on page 3.

curl https://qsc-dev.quasiris.de/api/v1/search/ab/products?q=wago&f.available=true&f.categories=Reihenklemmen&sort=pricdesc&page=3

POST API

It is also possible to query the API with a POST The POST API integration is recommended for more complex queries and Single Page Applications (SPA)

Example Request

This example request contains all possible parameters and filters.

{
"q": "*",
"rows": 10,
"page" : 1,
"requestId": "cdee7a05-8639-4121-a114-7942ba09aa1e9",
"requestOrigin": "my-app",
"trackingTags" : ["foo", "bar"],
"parameters": {
"foo": [
"bar"
]
},
"searchFilters": [
{
"id": "categoryId",
"values": [
"2286"
]
},
{
"id": "publishDate",
"filterDataType": "date",
"filterType": "range",
"minValue": "2024-02-01",
"maxValue": "2001-02-01"
},
{
"id": "price",
"filterType": "range",
"minValue": 0.99,
"maxValue": 11.11
}
],
"sort": {
"sort": "publishDate_asc"
},
"result" : {

}
}
  • q - the search query (default: *)
  • requestId - the request id used for tracking
  • requestOrigin - a identifier where the search is integrated. This parameter is used for tracking
  • parameters - a key value map to specifiy custom parameters
  • trackingTags - a list of custom tracking tags - for example test requests can be tagged and filtered later in analytics
  • result - can define the returned values in more detail. e.g.:
    • disable facets
    • disable paging
    • disable spellcheck
    • disable variant
    • define a length in a field of a document

Result

Enable / Disable facets - default: true

Enabled

{
"result" : {
"facet" : {
"enabled" : true
}
}
}

Disabled

{
"result" : {
"facet" : {
"enabled" : false
}
}
}

Configure display facets

{
"result" : {
"facet" : {
"facets" : {
"timestamp" : {},
"created_at" : {}
}
}
}
}
  • return the timestamp and created_at facet in the response.
  • Only configured facets can be displayed, to avoid access to all data of the index

Configure display fields

{
"result" : {
"document" : {
"fields" : {
"_score": {},
"id" : {}
}
}
}
}

Returns the fields _score and id in the response. Only configured fields can be displayed, to avoid access to all data of the index

Paging

  • page - the selected page (default: 1)
  • rows - the number of rows returned in the result, the default is specified in qsc-console

The QSC has a default limit for paging more than 10,000 documents due to a few important reasons related to performance and system stability:

  • Performance Concerns: Retrieving very large volumes of data in a single query can be extremely resource-intensive. As the depth of paging increases (i.e., as you move further and further from the first page), the query becomes slower. This is because the search engine has to count and then skip over a large number of documents to retrieve the data you're asking for, which consumes more memory and CPU.
  • Deep Pagination Issues: When QSC performs a search, it essentially ranks all documents that match the search criteria and then provides the top results based on the ranking. To retrieve results beyond the initial set (like the 10,001st document), the search engine must hold onto the interim results of potentially millions of documents. This can cause significant overhead and affect overall search engine health.
  • Memory Usage: The deeper you paginate, the more memory is used. This can lead to issues such as increased garbage collection times, slower response times, and even OutOfMemory errors, which might destabilize the cluster.
  • Scalability and Stability: By defaulting to limit deep pagination, QSC encourages practices that are scalable and stable.

If you need to retrieve more than 10,000 documents use the nextPageToken parameter. This method provide a way to retrieve large datasets without encountering performance degradation or stability issues. Both the GET and the POST API support the nextPageToken parameter.

For GET requests use the nextPageToken in the query parameters of the url.

  • in the first request set the nextPageToken=init
  • in the result use the paging.nextPage.token for the next requests nextPageToken=FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0
{
"paging": {
"nextPage": {
"token": "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0"
},
"pageCount": 2,
"rows": 24
}
}
  • call the api until the result.documents[] is empty

For `POST requests use the nextPageToken in the request body

{
"q" : "*",
"nextPageToken" : "init"
}
``

#### Filter
As a default the filter is handled as a term filter.
```json
{
"searchFilters": [
{
"id": "categoryId",
"operator" : "AND",
"values": [
"2286"
]
}
]
}
  • id - the id of the filter
  • values - a array of values
  • operator - all values are linked by this operator (default: OR) OR AND NOT

Date Range Filter

{
"searchFilters": [
{
"id": "publishDate",
"filterDataType": "date",
"filterType": "range",
"minValue": "2024-02-01",
"maxValue": "2001-02-01"
}
]
}
  • id - the id of the filter
  • filterDataType - the data type of the filter
  • filterType - specify a range filter
  • minValue - the min value or from value
  • maxValue - the max value or to value
  • for minValue and maxValue the ISO date format is supported

For a date range filter filterDataType: date and filterType:range must be set.

Double Range Filter

{
"searchFilters": [
{
"id": "price",
"filterType": "range",
"minValue": 0.99,
"maxValue": 11.11
}
]
}

Sorting

{
"sort": {
"sort": "publishDate_asc"
}
}


Example Response:

{
"currentTime": "2020-02-22T12:34:56+0000",
"request": {
},
"result": {
},
"statusCode": 200,
"time": 123
}

Every response will return a request time currentTime, total execution time time and a http statuscode statusCode. Some common status codes are listed in the table below

http codedescription
200OK
400Bad Request (Probably wrong parameters or url structure)
401Unauthorized (Credentials required)
403Forbidden (Not authorized for this user/ role)
500Internal server error

The other response entities will be described in more detail below.

Request

The response contains request informations like parameters, path, query, url required for the frontend search-request-building described below, but its also helpful for debugging purposes.

Example Response:

{
"currentTime": "2020-02-22T12:34:56+0000",
"request": {
"method": "GET",
"parameters": {
"f.available": [
"true"
],
"f.categories": [
"Reihenklemmen"
],
"page": [
"3"
],
"q": [
"wago"
],
"sort": [
"pricdesc"
]
},
"path": "/api/v1/search/ab/products",
"query": "q=wago&f.available=true&f.categories=Reihenklemmen&sort=pricdesc&page=3",
"url": "http://qsc-dev-admin/api/v1/search/ab/products?q=wago&f.available=true&f.categories=Reihenklemmen&sort=pricdesc&page=3"
},
"result": {
},
"statusCode": 200,
"time": 123
}

Result

The search response contain one or more search result, where each contains the found documents with the total number of hits and additional meta-information required for frontend building or further back-end processing. Each result has a unique name, its own statusCode and execution time.

Example Response:

{
"currentTime": "2020-02-22T12:34:56+0000",
"request": {
},
"result": {
"products": {
"name": "products",
"documents": [
],
"facets": [
],
"sliders": [
],
"paging": {
},
"statusCode": 200,
"statusMessage": "OK",
"time": 22,
"total": 1792
}
},
"statusCode": 200,
"time": 123
}

Documents

The found documents are returned as list, where each document is a key-value map. The value can be any simple-, list- or any complex data-type.

Example Response:

{
"currentTime": "2020-02-22T12:34:56+0000",
"request": {
},
"result": {
"products": {
"name": "products",
"documents": [
{
"document": {
"categories": [
"Reihenklemmen"
],
"description": "Mini-WSB-Beschriftungskarte als Karte bedruckt 50 ... 99 (2x) nicht dehnbar Aufdruck waagerecht aufrastbar weiß",
"ean": "4017332253505",
"keywords": [
"Reihenklemmen",
"Verteiler & Einbaugeräte",
"Kabelschuhe",
"247524",
"WAGO Kontakttechnik",
"WAGO"
],
"name": "WAGO 247-524 Schnellbezeichnungssystem Mini-WSB weiß",
"previewImageUrl": "https://images.alexander-buerkle.cloud/cdn-cgi/image/width=700,quality=85,format=auto/https://images.deha.de/?file=B36FB7E531AB743AE05332C8A8C00C3D&preset=674x428",
"sku": "0016874",
"supplierProductNumber": "247-524"
},
"fieldCount": 8,
"id": "ec8c6918-2643-4ec9-aa76-d427f3c76052"
}
],
"facets": [
],
"sliders": [
],
"paging": {
},
"statusCode": 200,
"statusMessage": "OK",
"time": 22,
"total": 1792
}
},
"statusCode": 200,
"time": 123
}

The App specific configuration can be found here under "Searching" tab.

The push or feeding-configuration is out of scope of this topic.

Facets

The facets are auto-generated filters where each facet has a unique id, filterName, some meta-information and a list of values which represent a single filter.

A facet can be applied by appending the filterName to the request url as query-parameter. For this purpose each facet value has a filter that is already url-encoded and only needs to be append to the request url. The count show how many documents will be found, when this filter will be applied and the selected attribute is the boolean indicator for this. Multiple facet values can be selected - the backend automatically determine which facet values are available/ selectable and return them in the response.

To remove a facet filter the filterName must be removed from the url query-parameter list.

Example Response:

{
"currentTime": "2020-02-22T12:34:56+0000",
"request": {
},
"result": {
"products": {
"name": "products",
"documents": [
],
"facets": [
{
"count": 2,
"filterName": "f.available",
"id": "available",
"name": "Verfügbar",
"resultCount": 2121,
"selected": true,
"values": [
{
"count": 1792,
"filter": "f.available=true",
"selected": true,
"value": "true"
},
{
"count": 329,
"filter": "f.available=false",
"value": "false"
}
]
},
{
"count": 2,
"filterName": "f.supplierName",
"id": "supplierName",
"name": "Hersteller",
"resultCount": 1792,
"values": [
{
"count": 1791,
"filter": "f.supplierName=WAGO+Kontakttechnik",
"value": "WAGO Kontakttechnik"
},
{
"count": 1,
"filter": "f.supplierName=PHOENIX++CONTACT",
"value": "PHOENIX CONTACT"
}
]
},
{
"count": 10,
"filterName": "f.categories",
"id": "categories",
"name": "Kategorie",
"resultCount": 2825,
"selected": true,
"values": [
{
"count": 1792,
"filter": "f.categories=Reihenklemmen",
"selected": true,
"value": "Reihenklemmen"
},
{
"count": 313,
"filter": "f.categories=Industrielle+Netzwerktechnik",
"value": "Industrielle Netzwerktechnik"
},
{
"count": 266,
"filter": "f.categories=Kennzeichnungsmaterial",
"value": "Kennzeichnungsmaterial"
},
{
"count": 175,
"filter": "f.categories=Dosen-+%26+Installationsklemmen",
"value": "Dosen- & Installationsklemmen"
},
{
"count": 79,
"filter": "f.categories=Relais+Industrie",
"value": "Relais Industrie"
},
{
"count": 75,
"filter": "f.categories=Netzger%C3%A4te%2C+Trafos+%26+Stromversorgungen",
"value": "Netzgeräte, Trafos & Stromversorgungen"
},
{
"count": 48,
"filter": "f.categories=Stromwandler",
"value": "Stromwandler"
},
{
"count": 47,
"filter": "f.categories=Trennschaltger%C3%A4te%2C+Mess-%2C+%26+Regler-Relais",
"value": "Trennschaltgeräte, Mess-, & Regler-Relais"
},
{
"count": 17,
"filter": "f.categories=Sensor-Aktor+Kabel",
"value": "Sensor-Aktor Kabel"
},
{
"count": 13,
"filter": "f.categories=sonstiges+Werkzeug",
"value": "sonstiges Werkzeug"
}
]
},
{
"count": 0,
"filterName": "f.category",
"id": "category",
"name": "Kategorie",
"resultCount": 0,
"values": []
}
],
"sliders": [
],
"paging": {
},
"statusCode": 200,
"statusMessage": "OK",
"time": 22,
"total": 1792
}
},
"statusCode": 200,
"time": 123
}

The App specific configuration can be found here under "Facets" tab.

Sliders (Deprecated)

!Deprecated: The sliders are now part of the facets. A slider is a special facet with the type slider. The behavior has been changed to position the sliders in the facet list.

The slider behavior is similar to facets. A slider can be applied by specifying a range, for example searching a document in price range 50 to 129.90 would be f.price=50,129.90

Example Response:

{
"currentTime": "2020-02-22T12:34:56+0000",
"request": {
},
"result": {
"products": {
"name": "products",
"documents": [
],
"facets": [
],
"sliders": [
{
"count": 405,
"filterName": "f.price",
"id": "price",
"maxRange": 145.0,
"maxValue": 145.0,
"minRange": 15.0,
"minValue": 53.0,
"name": "Preis",
"selected": true
}
],
"paging": {
},
"statusCode": 200,
"statusMessage": "OK",
"time": 22,
"total": 1792
}
},
"statusCode": 200,
"time": 123
}

The App specific configuration can be found here under "Sliders" tab.

Filters

There are 3 different ways to filter a search result.

  • term filter
  • range filter for numbers
  • daterange filter to filter dates
  • humandate filter
Term Filter

The term filter is used to filter string values.

Example

f.type=electronics

Range Filter

The Range filter is used to filter number ranges. The * operator can be used for min and max ranges.

Examples

Filter all products with a price between 12.92 and 99.95

f.price.range=12.95,99.95

Filter all products with a price greater than 12.92

f.price.range=12.95,*

Filter all products with a price less than 99.95

f.price.range=*,99.95

Date Range Filter

The date range filter is used to filter date ranges. The * operator can be used for min and max ranges.

Examples

Filter all news that are published between 23.6.2021 - 23.6.2022

f.publication_date.daterange=2021-06-23T00:00:00Z,2022-06-23T00:00:00Z

Filter all news that are newer than 23.6.21

f.publication_date.daterange=2021-06-23T00:00:00Z,*

Filter all news that are older than 23.6.2022

f.publication_date.daterange=*,2022-06-23T00:00:00Z

Human Date Filter

The human date filter can be used to filter for relative dates.

  • vergangenheit

  • past

  • zukunft

  • future

  • last day

  • yesterday

  • gestern

  • today

  • heute

  • last 3 days

  • letzten 3 tage

  • letzten 7 tage

  • letzten 30 tage

  • this week

  • diese woche

  • last week

  • letzte woche

  • last 3 month

  • letzten 3 monate

  • letzten 6 monate

  • this month

  • dieser monat

  • last month

  • letzter monat

  • last year

  • letztes jahr

  • this year

  • dieses jahr

  • Examples Filter all news that are newer than now

f.publication_date.humandate=future

Pagination

The paging entity display useful information for the frontend

Example Response:

{
"currentTime": "2020-02-22T12:34:56+0000",
"request": {
},
"result": {
"products": {
"name": "products",
"documents": [
],
"facets": [
],
"sliders": [
],
"paging": {
"currentPage": 3,
"firstPage": {
"currentPage": false,
"number": 1
},
"lastPage": {
"currentPage": false,
"number": 25
},
"nextPage": {
"currentPage": false,
"number": 4
},
"pageCount": 25,
"previousPage": {
"currentPage": false,
"number": 2
},
"rows": 72
},
"statusCode": 200,
"statusMessage": "OK",
"time": 22,
"total": 1792
}
},
"statusCode": 200,
"time": 123
}

The App specific configuration can be found here under "Page Config" tab.

Caching

The configuration of a search is cached 5 minutes. This improves performance significantly. For debugging and testing new configurations it is possible to disable the cache for a specific request. To disable the cache in the GET and the POST the query parameter ctrl=noCache must be sent in the request.

Sort

The sort property return all sort options. In the frontend the sort options can be rendered as a dropdown and the user can change the sorting for the result page.

  • id: the id of the sort entry. The id is used in the request to change the sorting
  • name: the name of the sort entry. The name can be used to display a text in a drop down in the frontend.
  • selected:
    • true: this sort options was selected in the request
    • false (default): this sort options was not selected in the request

Example Response:

{
"currentTime": "2020-02-22T12:34:56+0000",
"request": {
},
"result": {
"products": {
"name": "products",
"documents": [
],
"facets": [
],
"sliders": [
],
"paging": {
},
"sort": {
"sort": [
{
"id": "titleAZ",
"name": "Title A-Z"
},
{
"id": "lastUpdate",
"name": "Last Update",
"selected": true
}
]
},
"statusCode": 200,
"statusMessage": "OK",
"time": 22,
"total": 1792
}
},
"statusCode": 200,
"time": 123
}

The sort options can be configured in the search configuration under "Sorting" tab. It is also possible to change the sort options for each category. TODO link to a detailed description

Redirect

For some queries redirects can be configured. The redirect information can be found in result.products.redirect

Example Response:

{
"currentTime": "2020-02-22T12:34:56+0000",
"request": {
},
"result": {
"products": {
"name": "products",
"documents": [
],
"facets": [
],
"sliders": [
],
"paging": {
},
"redirect": {
"httpCode": 301,
"location": "https://example.com/example-product"
},
"statusCode": 200,
"statusMessage": "OK",
"time": 22,
"total": 1792
}
},
"statusCode": 200,
"time": 123
}

The App specific configuration can be found here.

Search-request-building Guide

On a search page there are typically different kind of actions available like submit query, click on link/ facet, use a slider, paginate or just sort by a field. Each action must be send to the search-engine, so that a new search, adjustment of or navigation through the search results can be performed.

The table below show with information must be provided to the search-engine with a search-request for a specific search-action. However these are best-practices with can differ per use-case/ requirement.

search-actionappend paramsremove params
submit querynoneall
click filter (facet, navigation, filter, move slider)query, filter, sortpage
perform sortquery, filterpage
paginate pagequery, filter, sortnone

Search page behaviour

actiondocumentsfilterpaginationsortingsearch boxpage
select filterreloadkeep other filtersreset--jump to top
remove filterreloadkeep other filtersreset--jump to top
use sliderreloadkeep other filtersreset--jump to top
change sortingreload-resetchange-jump to top
type in suggest box----show suggest-
submit a searchreloadresetreset-hide suggestjump to top
click on document------
change pagereload-change--jump to top
change rowsreload-reset--jump to top

Human Date Filter

The human date filter allow to filter date ranges in a human way.

For example:

  • filter all date values in the past for the field myDate

f.myDate.humandate=past

In the followin table all human date filter values are listed.

ValueDescription
vergangenheit
past
zukunft
future
last day
yesterday
gestern
today
heute
last 3 daysinstead of 3, any number can be used
letzten 3 tage
letzten 7 tage
letzten 30 tage
this week
diese woche
last week
letzte woche
last 3 monthinstead of 3, any number can be used
letzten 3 monate
letzten 6 monate
this month
dieser monat
last month
letzter monat
last year
letztes jahr
this year
dieses jahr