Akinon Release Notes (05/12/2025) are now live! Click here to learn what's new.
LogoLogo
API Reference
  • Home
  • Quick Start
  • Tutorials
  • Technical Guides
  • Release Notes
  • Glossary
  • Welcome to Akinon Technical Guides
  • ACC
    • ACC CLI
    • Create Application via CLI
    • Deploy Environment Variables
    • App Store for Developers
  • Omnitron
    • Product Types
    • Product Categorization
    • Splitting a Merged Order Item
  • Commerce
    • Shipping Rules Calculator
    • Data Source Shipping Options
    • Attribute Based Shipping Options
    • Filtering Products
    • Conversation & Messages
    • Sitemap Configuration
    • Weight-Based Product Sales
    • Group Attribute Sets
    • Contract Management
    • Find in Store for Whippy Ware
    • Plugins
    • Remote Price
    • E-mail Templates
    • Loyalty Accounts
    • Search Structure
    • User Segmentation & Rules
    • Promotions
  • OMS
    • Getting Started with OMS
    • Basic Setup
    • Scenarios
    • Capacity Feature
    • Package Management
      • Packages
      • Transfer
      • States
    • Commands
      • Packages
        • Package Command Parameters
        • DeAllocate Package Reservations Command
        • Channel Based Complete Packaging without Shipment Command
        • Complete Packaging with Shipment Command
        • Complete Packaging without Shipment Command
        • Package Refuse with Denial Reason Command
        • Product Not Found & Wrong Product Command
        • Product Not Found & Wrong Product Command Advanced
        • Package Packed for Refund Command
        • Block The Package For Action Command
        • Unblock the Package For Action Command
        • Update The Package’s Invoice
        • Manual Planning Command
      • Transfer
        • Transfer Order Advanced Command
        • Product for Transfer Not Found & Wrong Product Command
        • Transfer Delivered Command
        • Transfer Dispatch Command
        • Transfer Ready for Dispatch Command
        • Transfer Out Of Stock
      • Shipment
        • Shipment Order Command
        • Package Advanced Shipment Command
        • Ship The Package Command
        • Ship The Package without Shipment Integration Command
        • Update The Package’s Shipment Status Command
        • Update Shipment Info of Package Command
    • Inventory Locations & Engine
      • Properties & Domain Relation
      • Customization
      • Inventory Engine
    • Fulfillment
      • Shipments
      • Invoice Integration
    • Webhooks
      • Webhook Examples
        • Order Webhook
        • Package Webhook
        • Shipment Webhook
        • Stock Location Webhook
        • Transfer Webhook
    • Integrating OMS with Seller Center
  • Instore
    • Getting Started
    • Cash Register Integration
    • OTP (One Time Password) Process
    • Services
      • Password Reset Services
  • Marketplace Dashboard
    • N11 Marketplace Setup Configurations
    • Trendyol Marketplace Setup Configurations
    • Walmart Marketplace Setup Configurations
    • Amazon Marketplace Setup Configurations
    • Hepsiburada Marketplace Setup Configurations
  • Project Zero
    • Django
      • Basic Setup
      • Project Structure
        • Templates & Components
        • Private Dependencies
        • Omnife Project Submodule
        • Webpack
        • ESLint Rules
        • Bundles
        • Multilanguage & Translation
        • Environmental File
        • Custom Error Pages
        • Icon Font
      • Page Types
        • Static Pages & Flatpages
        • Account Page
          • Template Rendering in Account Pages
          • Forms & Validation
        • Basket Page
          • Redux Basket State
          • Basket Page - View
        • Checkout
          • Redux Checkout State
          • View & Template Rendering
          • Masking & Validation
      • Theming & Styling
      • Widgets
      • SEO Management
      • Extending Project Zero
    • Next.js
      • Basic Setup
      • Deployment
      • Static Assets
      • Plugins
      • Widgets
      • Icons
      • Localization
      • SEO Management
      • Advanced Usage
      • Data Fetching
        • Client
          • Account
          • Address
          • Basket
          • Checkout
          • Misc
          • Product
          • User
          • Wishlist
        • Server
          • Category
          • Flat Page
          • List
          • Menu
          • Product
          • SEO
          • Special Page
          • Widget
  • App Maker
    • Setup Your Environment
    • Plugin Quickstart
    • Create Project
    • Setup Existing Project
    • Deploy Project
    • Users and Roles
    • Add Public Key
    • App Maker CLI
    • Create App on Stores
      • Creating App on Apple App Store
      • Creating App on Google Play Store
    • Mobile App Framework
      • Configuration
      • Framework
      • Project Structure
        • Structure
        • Data Containers
        • Pages
      • Dependency Integration
        • Plugins
        • Akinon Plugin Adapter
  • Akifast
    • HPP
      • Getting Started
      • Authorization
      • Payment Session Creation
        • Key Points Before Creating a Payment Session
        • Creating Payment Session
        • Redirecting to the Payment Page
        • Errors Encountered During Payment Session Creation
      • Merchant Services
        • Shipping Query URL
        • Agreement Query URL
        • Other URLs
  • B2B
    • Getting Started
    • B2B Setup
  • Adds-on
    • Invoicer
      • Introduction
      • Invoice & Pay On Delivery Service
  • Channel App Template
    • Introduction
    • Installation and Usage
    • Development Steps
      • Folder Structure
      • Starting Step
      • Encoding the Sales Channel
        • Introduction
        • Setup
        • Products
        • Product Price
        • Product Stock
        • Product Image
        • Orders
        • Product Data
      • Adding a New Command to Akinon
      • Listening for External Requests
    • Architecture
      • Introduction
      • Integration
      • Services (Flows)
        • Introduction
        • Product Service
        • Price Service
        • Stock Service
        • Image Service
        • Order Service
  • Multi Regional Settings
    • Multi Regional Settings
Powered by GitBook

© 2025 Akinon. All rights reserved.

On this page
  • Search Structure
  • Acceptable Parameters for the Request
  • Sending a Request to ElasticSearch
  • Filtering Flow on the Shop Screen
  • Dynamic Settings Used Under Search
  • Settings Edited via Omnitron
  • Sort Options
  • AutoComplete
  • Sent Requests
  • Index Configuration
  • POST https://{storefront_url}/api/v1/index-configurations/
  • Compatibility of IndexConfigurations with Facets
  • POST https://{storefront_url}/api/v1/facet/

Was this helpful?

  1. Commerce

Search Structure

This document provides a comprehensive guide on the features and functionalities, and standard operating instructions for the Commerce Search Structure.

Search Structure

The search functionality on the Commerce side is offered through the "/list" endpoint. Triggering the search structure involves sending a request to this endpoint. The Commerce search structure relies on the usage of "ElasticSearch". When the application is initialized, the relevant search/elastic settings are provided to Django via apps.py. The corresponding view and method can be found at omnishop.search.resources.views.FacetView.get.

FacetView Get:

def
get
(self, request, search_text=None, eparams=None,
index_name=None, default_page_size=None,
elasticsextra_search_arch_value=None,
extraction_strategy=None, inventory_strategy=None):

Acceptable Parameters for the Request

Possible Parameters in the Request for the respective endpoint:

  1. search_text: The keyword to search for.

  2. extra_search_param: Used for filtering based on fields such as in_stock, price, basket_offer_ids, category_ids, collection_ids.

  3. index_name: The index to search in Elasticsearch.

  4. default_page_size: The number of products for pagination.

  5. elasticsearch_value: Used to select a sorter based on the elasticsearch_value found in Sort Options in the database.

  6. extraction_strategy: The method used for extracting products from the response received from Elasticsearch.

  7. inventory_strategy: Specifies which price inventory to use in shops with multiple inventories."

After the request is made, the search result is first checked to see if the same search has been previously performed using both the local Redis and default Redis servers. If a previous search with the same parameters has been made, the result is quickly retrieved from the cache. To achieve this, after the request is received and the "get" method is called, the "_get" method is invoked to check if the specified search exists in the cache. An example is provided below:

The expiration durations for the cache layers are as follows:

  • L1 Cache Layer (Local Redis): 60 seconds

  • L2 Cache Layer (Shared Redis): 120 seconds

Search Get Cache:

data = self.get_cache(
index_name=index_name, page=page, page_size=page_size,
search_params=search_params, search_text=search_text,
sorter=sorter, site_id=site_id,
elasticsearch_value=elasticsearch_value,
extraction_strategy=extraction_strategy,
inventory_strategy=inventory_strategy,
cache_breaker=cache_breaker(request),
currency=get_current_currency(request),
)

When a search is received that has not been previously performed, the cache layer will not have the result available, and the normal search process will be initiated. In this process, the Elasticsearch service is utilized. The SearchService in Omnishop > Search > services.py is responsible for handling this. Elasticsearch does not store the actual products and categories themselves. The necessary fields for querying include: in_stock, price, basket_offer_ids, category_ids, collection_ids.

Possible Search Params:

class
SearchService
(object):
facet_configuration_repository = FacetConfigurationRepository()
possible_search_params = (
'in_stock'
,
'price'
,
'basket_offer_ids'
,
'category_ids'
,
'collection_ids'
)

Sending a Request to ElasticSearch

When there is no data stored in the cache and a new search request is received, as mentioned above, no result can be obtained from the cache layer. Therefore, the normal search flow is initiated. In this process, the ElasticSearch service, as mentioned earlier, is involved. A request is sent to ElasticSearch to retrieve the relevant data. The parameters included in this request, along with their descriptions, are as follows:

  • index_name: The value of the query_param or the ES_INDEX value in the settings is used. If specified in the settings, the static ES_INDEX value is used, such as ES_INDEX="products".

  • inventory_strategy: The value of the query_param or the inventory_strategy of the basket is used. If the inventory_strategy is provided, the price field is replaced with price_1234, where 1234 is the price_list_id.

  • extraction_strategy: The value is taken from the query_param in the request. If the extraction_strategy value in the request is "None", the "get_search_product_extraction_strategy" method in omnishop.search.strategies is called. If defined in the settings, it takes the value of "SEARCH_PRODUCT_EXTRACTION_STRATEGY", otherwise, it takes the value of "omnishop.search.strategies.DefaultProductExtractionStrategy".

Inventory and Extraction Strategy:

def
_get
(self, request, search_text=None, extra_search_params=None,
index_name=None, default_page_size=None, elasticsearch_value=None,
extraction_strategy=None, inventory_strategy=None):
site_id = Site.objects.get_current().pk
default_page_size = min(default_page_size
or
self.default_page_size,
self.page_size_limit)
search_params = extra_search_params
and
extra_search_params.copy()
or
{}
params = request.GET.copy()
inventory_strategy = inventory_strategy
or
request.basket.inventory_strategy
—> extraction_strategy = extraction_strategy
or
get_search_product_extraction_strategy()

Default Extraction Strategy:

def
get_search_product_extraction_strategy
():
return
import_string(getattr(
settings,
'SEARCH_PRODUCT_EXTRACTION_STRATEGY'
,
→
'omnishop.search.strategies.DefaultProductExtractionStrategy'
))
  • In the next step, the Facet Fields are retrieved from Elasticsearch. These Facets essentially represent the information that can be used for filtering on the list screens of the shop websites. For example, categories, size, material, stock status, price, etc.

  • sorter: The value of the query_param or the default SortOption object found in the database is used. The elasticsearch_value field of the SortOption is the parameter used when making the request to Elasticsearch.

Filtering Flow on the Shop Screen

The Facet Fields and Sort Options are obtained during the execution flow of the "._search" method in the Search > Services > SearchService.

During the flow, the "._search" method is executed by the "Search Service" to retrieve the options for filtering on the list screen of shop websites. The Facet Fields are fetched from ElasticSearch for obtaining these filters. The "get_facet_fields" method is responsible for retrieving the facets.

When executing the method, the "facet_constructor" checks if the facet_field has any attributes, and if so, it configures the facets accordingly (e.g., aggregations, field, extraction_strategy). If there are no attributes and the facet_field's attribute_key is "category_ids", the size is set to 500. Otherwise, the default size is set to 100.

The FacetClass is executed to retrieve the matching values, and the key-value pairs of facet_fields for products are obtained. Then, the inventory_strategy is returned since the facet_fields, such as price_list and inventory_strategy, vary. For all defined filtering types in the database, the "._search" method executes the facet_generator and continues the flow.

The retrieved facets from Elasticsearch, which represent the attributes (e.g., in_stock), are used to filter the products. The IDs of these attributes are used to fetch their corresponding values from the database, and widgets are created using these values.

omnishop.search.services.SearchService._search

Facet Field and Sort Options code blocks that retrieve can be seen below.

facet_fields, max_score = get_facet_fields(
doc_type=doc_type,
search_text=search_text,
index=index_name,
search_fields=search_fields,
facet_field_constructor=self.facet_constructor,
search_kwargs=kw, extraction_strategy=extraction_strategy,
search_owner=search_owner,
inventory_strategy=inventory_strategy)
sorters, selected_sorter = get_sorters(
sorter, elasticsearch_value=elasticsearch_value,
inventory_strategy=inventory_strategy)

The data type responsible for providing sorting on the product list page in the shop is the sort_options data type. This data type is stored in the database and managed by Omnitron for related operations.

pre_filter_kwargs and pre_exclude_kwargs are parameters that can be sent to add dynamic rules if desired. They are managed through settings.

In the settings, under Dynamic Settings, you can add the following examples for SEARCH_PRE_FILTER_KWARGS and SEARCH_DYNAMIC_FILTER:

Kwargs Dynamic Filters:

SEARCH_DYNAMIC_FILTER = {
'cache_breaker'
: is_user_vip,
'filter'
:filter_by_vip,
}

Search Pre Filter Kwargs Dynamic Settings:

DYNAMIC_SETTINGS = {
'1'
:{'SEARCH_PRE_FILTER_KWARGS': {'products.category_ids'
:[u'761'
]},'CATEGORY_PRE_FILTER': Q(pathstartswith='000100010'),'CATEGORY_DETAIL_MAX_DEPTH'
: CATEGORY_DETAIL_MAX_DEPTH,'MENU_DEFAULT_PARENT_UUID':
'37eb236a-2c0e-4338-a926-d90602e5726d'
,}}

The pre_filter_kwargs and pre_exclude_kwargs values are utilized in the omnishop.search.services.SearchService._search method of the SearchService.

Pre Filter and Exclude Kwargs:

pre_filter_kwargs = self._get_pre_filter_kwargs()
pre_exclude_kwargs = {}

To dynamically add rules to the pre_filter_kwargs value mentioned above, as indicated, this value is obtained through dynamic_settings. For this purpose, the "SEARCH_PRE_FILTER_KWARGS" value is retrieved via the "_get_pre_filter_kwargs()" method.

Relevant code block can be seen below:

Getting Pre Fılter Kwargs From Dynamic Settings:

def
_get_pre_filter_kwargs
(self):
filter_kwargs = getattr(dynamic_settings,
'SEARCH_PRE_FILTER_KWARGS'
,
{})
return
filter_kwargs

min_score: When querying products in Elasticsearch, those with scores below this value are excluded. This value can be managed with settings.

Es Min Score Coefficient:

ES_MIN_SCORE_COEFFICIENT = env(
"ES_MIN_SCORE_COEFFICIENT"
,
cast=float, default=
0
)

After receiving a response from Elasticsearch with the information above, the product extraction process takes place. For this purpose, there are several ProductExtractionStrategies available. If the extraction strategy is not specified in the request, the DefaultProductExtractionStrategy is used.

Strategies:

  • DefaultProductExtractionStrategy: Retrieves all product_ids that match the query.

  • FirstItemSearchExtractionStrategy: Retrieves the first item from the list of sub-products.

  • ListableFirstProductExtractionStrategy: Retrieves listable products that are included in the meta product's sub-products.

  • MinPriceFirstProductExtractionStrategy: Sorts the sub-products based on the minimum product price in ascending order (a-z) and retrieves the first product.

  • MaxPriceFirstProductExtractionStrategy: Sorts the sub-products based on the maximum product price in ascending order (a-z) and retrieves the first product.

  • AllSubProductsExtractionStrategy: Retrieves all sub-product ids belonging to the meta product.

After obtaining the facets and product IDs from Elasticsearch, conversion processes are performed as follows:

  1. Product Convert: The product_ids received from Elasticsearch are used to retrieve products from the database, maintaining their original order.

  2. Facet Convert: The facets (attribute filters) received from Elasticsearch are used to retrieve attribute values from the database, which can be used to filter the products. Widgets are created based on these attribute values. At this stage, different widgets are created based on the attribute keys.

If a Facet Configuration is specified for a relevant attribute key, a widget is created accordingly. For category_ids, a Category Widget is created. For basket_offer_ids, a Promotion Widget is created. For the Attribute Value Widget, attribute keys should be provided in the settings.

  • For category_ids, create a Category Widget.

  • For basket_offer_ids, create a Promotion Widget.

  • For the Attribute Value Widget, attribute keys should be provided in the settings.

Landing Page Attributes:

LANDING_PAGE_ATTRIBUTES = [
'brand'
]

If none of the above conditions are met, the attribute key will default to creating a Multi Select Widget. After the conversion process, the response is generated. The response includes the following fields:

Fields:

  1. facets

  2. sorters

  3. search_text

  4. products

Dynamic Settings Used Under Search

The dynamic settings configurations that exist beneath the search structure on the Shop side and are utilized in the workflow are summarized below, along with their purposes.

1. HIDE_GROUPED_PRODUCTS_ON_SEARCH

Why is it used?

It is used to remove combination product listings from the search structure.

How does it work?

When this setting is enabled, during indexing, the "name" and "search" fields of the Elasticsearch product object are set as empty strings. This means that when group products are sent to Elasticsearch, the "name" and "search" fields are sent as empty strings when this setting is enabled.

2. PRODUCT_STOCK_OUT_VISIBILITY_ENABLED

Why is it used?

It is used to display out-of-stock products as "sold out" on the listing page.

How does it work?

The setting "PRODUCT_STOCK_OUT_VISIBILITY_ENABLE" is set to True in the dynamic settings. This enables the functionality to display products as "sold out" when they are out of stock on the listing page.

3. SEARCH_DEFAULT_PAGE_SIZE

Why is it used?

It is used to dynamically change the page size on the product listing page. For example, instead of loading a new page with 20 products, it can be changed to load a new page with 24 products, allowing for flexibility in the number of products displayed.

How does it work?

The dynamic setting "SEARCH_DEFAULT_PAGE_SIZE" is used with an integer value desired for the page size, along with a minimum value also provided as an integer. This setting allows for the customization of the page size on the product listing page.

Settings Edited via Omnitron

Sort Options

Under the section Requesting Elasticsearch, it was mentioned that sort options are the data type responsible for sorting on the product listing page in the shop. The addition, modification, or removal of these options is controlled through Omnitron. The steps to perform these actions are as follows:

  1. Access the Settings section in the Omnitron panel.

  2. Click on the Sorting Algorithms field in the opened screen.

  3. On the opened screen, you can see the sorting configurations for the relevant catalogs under the headings of names, sorting types, and visibility.

  4. By clicking on the relevant sorting algorithm, you can make edits, or you can add a new sorting algorithm using the New Sorting Algorithms field located in the top right corner.

AutoComplete

The autocomplete system automatically starts working when a character is entered in the search field. It takes the entered search_text as a parameter and begins executing within the autocomplete function. If there is no search_text provided when this service runs, the suggested results will return as an empty list. In this section, the products stored in Elasticsearch are queried. Multiple matches are aimed to be achieved by using different types in these queries. Additionally, the ES_MIN_SCORE_COEFFICIENT value is included when querying the products. If this value is greater than zero, the min_score value received from here is added, and the query is updated accordingly.

The obtained search object is then modified based on the configurations defined in the sort and pre_filter functions, respectively. As a result of these sorting operations, the four most suitable results are returned based on the search_text. These four results represent product_ids. These products are automatically listed on the search label.

Additionally, a listing process is performed for categories as well. The products are checked, and if they have categories and there are relevant results, they are also listed and shown at the top of the search results.

Sent Requests

Search

url(
r'^list/'
, FacetView.as_view(), name=
'search'
)
router.register(
r'sort_options'
, SortOptionViewSet)
router.register(
r'facet'
, FacetConfigurationViewSet)
router.register(
r'product_sorting_items'
, ProductSortingItemViewSet)
Shomnipro url(
r'^autocomplete/'
, AutocompleteView.as_view(),
name=
"autocomplete"
)

Index Configuration

IndexConfiguration is a model that enables the addition of custom values to Elasticsearch. By creating an IndexConfiguration, numeric attribute values can be indexed in Elasticsearch, allowing for their later use for various purposes.

There are a few points to pay attention to here. First, we expect the attribute value to be numeric or convertible to a numeric value. For example, values like 1, 100, or "50" are acceptable at this stage. However, if our attribute values contain different formats, such as "30 cm" or "10x20x50," non-numeric values will not be indexed. To create an IndexConfiguration object, a sample request should look like this:

POST https://{storefront_url}/api/v1/index-configurations/

Request

{ "name": "Index configuration name", "attribute_key": "exist_attribute_name", "attribute_type": "integer" }

All three fields must be included in the body. The 'name' field should correspond to an existing 'attribute_key'; you cannot pre-add it for a non-existent attribute in the system. The 'attribute_type' value can be integer, float, or long. If a request is made for a non-existent 'attribute_key,' the response will be as follows:

Response

{ "attribute_key": [ "Attribute with key exist_attribute_name \ does not exist" ] }

Assuming a successful request with an existing 'attribute_key,' the response will be as follows:

Response

{ "pk": 1, "name": "Index configuration name", "attribute_key": "exist_attribute_name", "attribute_type": "integer" }

Compatibility of IndexConfigurations with Facets

After creating IndexConfigurations, the desired data will be indexed in Elasticsearch. The way data is used after this stage is up to the user. To illustrate how custom usage can work, let's assume we have successfully created an IndexConfiguration object as described above, and there are products associated with the attribute_key used in this object.

In order to create a rangable facet, you can create a new FacetConfiguration object. For example, after creating the IndexConfiguration object and indexing data into Elasticsearch, the key used for indexing is formed as "custom_" + indexconfiguration.attribute_key. For example, if our attribute_key in the defined object is 'exist_attribute_name,' the indexed value in Elasticsearch will be 'custom_exist_attribute_name.'

To ensure compatibility, our FacetConfiguration object should also have an attribute_key value of 'custom_exist_attribute_name.' This will allow us to create a facet for the indexed custom data.

Let's consider that our IndexConfiguration object is created with the following values:

{ "pk": 1, "name": "Index configuration name", "attribute_key": "exist_attribute_name", "attribute_type": "integer" } 

The values for the sample facet object we need to create should be defined as follows:

POST https://{storefront_url}/api/v1/facet/

Request

{ "pk": 1, "name": "Facet name", "attribute_key": "custom_integration_cap", "attribute_type": "global", "widget": "multi_select", "widget_kwargs": { "labels": {"1000":"1000 +", "100-1000":"100-1000","0-50":"0-50", "50-100":"50-100"}, "name": "Cap-Range", "order": 1 }, "facet": "range", "facet_kwargs": { "ranges": [["0-50",[0,49]],["50-100",[50,99]], ["100-1000",[100,999]],["1000",[1000,100000]]]}, "settings": {} }

With this created object, you can now use this filter for products with the indexed custom_integration_cap value on the listing page.

PreviousLoyalty AccountsNextUser Segmentation & Rules

Last updated 16 days ago

Was this helpful?