Search Using Kotlin SDK

The Experience Search API is a native, AI-powered, multi-modal search solution that enables personalized search experiences on your website or app. It supports:

  • Semantic Search: Understands natural language text queries, enabling you to deliver highly relevant search results that meet user expectations and drive conversions.
  • Visual Search: Enables users to search using images from their camera or gallery to find visually similar or relevant products.
📘

For more information see the following:

Semantic Search

Parameters

ParameterData Structure TypeMandatory?Description
pagePageYesInformation about the current page (screen name, referrer, categories)
textStringYesThe natural‑language query to process using Semantic Search
filtersListNoOptional attribute filters (brand, color, price range, and so on)
paginationPaginationYesDefines number of items and offset for pagination
sortBySortOptions?NoSorting rules (for example, by field or by relevance)
pageAttributesMap<String,PageAttribute>?NoKey–value attributes for campaign targeting or search context
branchIdString?NoBranch identifier for multi‑branch setups (stores, financial institutions, restaurants)
optionsSearchOptions?NoAdditional search configurations (for example, return analytics metadata)

Code example

suspend fun semanticSearch() {

    val result =
        DYSdk.getInstance()
            .search
            .semanticSearch(
                page = Page.homePage(pageLocation = "location"),
                text = "jeans",
                pagination = Pagination(numItems = 1u, offset = 2u)
            )

    when (result.status) {
        ResultStatus.SUCCESS,
        ResultStatus.WARNING -> {

            val choice =
                result.choice
                    ?: run {
                        Log.w("SemanticSearch", "No choice returned for semantic search result")

                        return
                    }

            val variation =
                choice.variations.firstOrNull()
                    ?: run {
                        Log.w("SemanticSearch", "No variations returned for semantic search result")

                        return
                    }

            val data = variation.payload.data

            // Optional meta information

            val custom = data.custom

            val totalNumResults = data.totalNumResults

            val spellCheckedQuery = data.spellCheckedQuery

            Log.d(
                "SemanticSearch",
                "Semantic search results: total=$totalNumResults, spellCheckedQuery=$spellCheckedQuery, custom=$custom"
            )

            // Handle product slots

            data.slots?.forEach { slot ->
                val productData = slot.productData as? DefaultRecsProductData ?: return@forEach

                val groupId = productData.group_id

                val name = productData.name

                val url = productData.url

                val price = productData.price

                val inStock = productData.in_stock

                val imageUrl = productData.image_url

                val categories = productData.categories

                val keywords = productData.keywords

                Log.d(
                    "SemanticSearch",
                    "Product: groupId=$groupId, name=$name, price=$price, inStock=$inStock, url=$url"
                )

                Log.v(
                    "SemanticSearch",
                    "Product details: imageUrl=$imageUrl, categories=$categories, keywords=$keywords"
                )
            }

            // Handle facets

            val facets = data.facets

            facets?.forEach { facet ->
                val column = facet.column

                val displayName = facet.displayName

                val type = facet.valuesType

                Log.d(
                    "SemanticSearch",
                    "Facet: column=$column, displayName=$displayName, type=$type"
                )

                when (facet) {
                    is NumberFacet -> {

                        val min = facet.min

                        val max = facet.max

                        Log.d("SemanticSearch", "Number facet range: min=$min, max=$max")
                    }
                    is StringFacet -> {

                        facet.values.forEach { stringValue ->
                            val name = stringValue.name

                            val count = stringValue.count

                            Log.d("SemanticSearch", "String facet value: name=$name, count=$count")
                        }
                    }
                }
            }
        }
        ResultStatus.ERROR -> {

            result.error?.let { exception ->
                Log.e("SemanticSearch", "Semantic search error: ${exception.message}", exception)
            } ?: Log.e("SemanticSearch", "Semantic search error: unknown error")
        }
    }
}

Visual Search

Parameters

ParameterData Structure TypeMandatory?Description
pagePageYesProvides screen context for the visual search request
imageBase64StringYesBase64‑encoded image to use for product matching
filtersListNoOptional attribute filters (brand, color, price range, and so on)
sortBySortOptions?NoSorting rules (for example, by field or by relevance)
pageAttributesMap<String,PageAttribute>?NoKey–value attributes for campaign targeting or search context
branchIdStringNoBranch identifier for multi‑branch setups (stores, financial institutions, restaurants)
optionsSearchOptions?NoAdditional search configurations (for example, return analytics metadata)

Code example

suspend fun visualSearch() {

    val result =
        DYSdk.getInstance()
            .search
            .visualSearch(
                page = Page.homePage(pageLocation = "location"),
                imageBase64 = "imageBase64"
            )

    when (result.status) {
        ResultStatus.SUCCESS,
        ResultStatus.WARNING -> {

            val choice =
                result.choice
                    ?: run {
                        Log.w("VisualSearch", "No choice returned for visual search result")

                        return
                    }

            val variation =
                choice.variations.firstOrNull()
                    ?: run {
                        Log.w("VisualSearch", "No variations returned for visual search result")

                        return
                    }

            val data = variation.payload.data

            // Optional meta information

            val custom = data.custom
            val totalNumResults = data.totalNumResults

            Log.d("VisualSearch", "Visual search results: total=$totalNumResults, custom=$custom")

            // Handle product slots

            data.slots?.forEach { slot ->
                val productData = slot.productData as? DefaultRecsProductData ?: return@forEach

                val groupId = productData.group_id

                val name = productData.name

                val url = productData.url

                val price = productData.price

                val inStock = productData.in_stock

                val imageUrl = productData.image_url

                val categories = productData.categories

                val keywords = productData.keywords

                Log.d(
                    "VisualSearch",
                    "Product: groupId=$groupId, name=$name, price=$price, inStock=$inStock, url=$url"
                )

                Log.v(
                    "VisualSearch",
                    "Product details: imageUrl=$imageUrl, categories=$categories, keywords=$keywords"
                )
            }

            // Handle facets

            val facets = data.facets

            facets?.forEach { facet ->
                val column = facet.column

                val displayName = facet.displayName

                val type = facet.valuesType

                Log.d("VisualSearch", "Facet: column=$column, displayName=$displayName, type=$type")

                when (facet) {
                    is NumberFacet -> {

                        val min = facet.min

                        val max = facet.max

                        Log.d("VisualSearch", "Number facet range: min=$min, max=$max")
                    }
                    is StringFacet -> {

                        facet.values.forEach { stringValue ->
                            val name = stringValue.name

                            val count = stringValue.count

                            Log.d("VisualSearch", "String facet value: name=$name, count=$count")
                        }
                    }
                }
            }
        }
        ResultStatus.ERROR -> {

            result.error?.let { exception ->
                Log.e("VisualSearch", "Visual search error: ${exception.message}", exception)
            } ?: Log.e("VisualSearch", "Visual search error: unknown error")
        }
    }
}