Skip to content

Exercise 5: E-commerce Search Optimization

📋 Exercise Details

  • Difficulty: Intermediate
  • Duration: 2-3 hours
  • Skills: Custom analyzers, scoring profiles, business logic implementation, performance optimization

🎯 Objective

Build a complete e-commerce search system that demonstrates advanced analyzer and scoring techniques. You'll create custom analyzers for product search, implement business-driven scoring profiles, and optimize for real-world e-commerce scenarios.

📚 Prerequisites

  • Completed Exercises 1-4
  • Understanding of e-commerce search requirements
  • Knowledge of business metrics (conversion rates, revenue impact)
  • Experience with JSON configuration and REST APIs

🛠️ Instructions

Step 1: Design E-commerce Search Requirements

Define the business requirements for your e-commerce search system:

Business Goals

  • Increase conversion rates by showing relevant products first
  • Boost revenue by promoting high-margin and popular items
  • Improve user experience with fast, accurate search results
  • Handle diverse queries from specific product names to general categories

Search Scenarios

  1. Product Name Search: "iPhone 14 Pro", "Dell XPS 13"
  2. Category Browsing: "laptops", "smartphones", "headphones"
  3. Feature-based Search: "wireless headphones", "gaming laptop"
  4. Brand Search: "Apple", "Samsung", "Sony"
  5. Typo Tolerance: "iphone" → "iPhone", "samsng" → "Samsung"

Step 2: Create E-commerce Index Schema

Design a comprehensive index schema for product search:

{
  "name": "ecommerce-products",
  "fields": [
    {
      "name": "productId",
      "type": "Edm.String",
      "key": true,
      "searchable": false
    },
    {
      "name": "name",
      "type": "Edm.String",
      "searchable": true,
      "analyzer": "product_name_analyzer"
    },
    {
      "name": "name_autocomplete",
      "type": "Edm.String",
      "searchable": true,
      "indexAnalyzer": "autocomplete_analyzer",
      "searchAnalyzer": "autocomplete_search_analyzer"
    },
    {
      "name": "brand",
      "type": "Edm.String",
      "searchable": true,
      "filterable": true,
      "facetable": true,
      "analyzer": "brand_analyzer"
    },
    {
      "name": "category",
      "type": "Edm.String",
      "searchable": true,
      "filterable": true,
      "facetable": true,
      "analyzer": "category_analyzer"
    },
    {
      "name": "description",
      "type": "Edm.String",
      "searchable": true,
      "analyzer": "description_analyzer"
    },
    {
      "name": "features",
      "type": "Collection(Edm.String)",
      "searchable": true,
      "filterable": true,
      "analyzer": "feature_analyzer"
    },
    {
      "name": "price",
      "type": "Edm.Double",
      "filterable": true,
      "sortable": true,
      "facetable": true
    },
    {
      "name": "originalPrice",
      "type": "Edm.Double",
      "filterable": true,
      "sortable": true
    },
    {
      "name": "rating",
      "type": "Edm.Double",
      "filterable": true,
      "sortable": true,
      "facetable": true
    },
    {
      "name": "reviewCount",
      "type": "Edm.Int32",
      "filterable": true,
      "sortable": true
    },
    {
      "name": "salesCount",
      "type": "Edm.Int32",
      "filterable": true,
      "sortable": true
    },
    {
      "name": "inventory",
      "type": "Edm.Int32",
      "filterable": true,
      "sortable": true
    },
    {
      "name": "inStock",
      "type": "Edm.Boolean",
      "filterable": true
    },
    {
      "name": "releaseDate",
      "type": "Edm.DateTimeOffset",
      "filterable": true,
      "sortable": true
    },
    {
      "name": "tags",
      "type": "Collection(Edm.String)",
      "searchable": true,
      "filterable": true,
      "analyzer": "tag_analyzer"
    },
    {
      "name": "imageUrl",
      "type": "Edm.String",
      "searchable": false
    },
    {
      "name": "url",
      "type": "Edm.String",
      "searchable": false
    }
  ],
  "analyzers": [
    {
      "name": "product_name_analyzer",
      "tokenizer": "standard",
      "charFilters": ["html_strip"],
      "tokenFilters": [
        "lowercase",
        "product_synonyms",
        "brand_preservation",
        "model_number_preservation"
      ]
    },
    {
      "name": "brand_analyzer",
      "tokenizer": "keyword",
      "tokenFilters": ["lowercase", "brand_synonyms"]
    },
    {
      "name": "category_analyzer",
      "tokenizer": "standard",
      "tokenFilters": ["lowercase", "category_synonyms"]
    },
    {
      "name": "description_analyzer",
      "tokenizer": "standard",
      "charFilters": ["html_strip"],
      "tokenFilters": [
        "lowercase",
        "english_stopwords",
        "product_synonyms",
        "feature_synonyms"
      ]
    },
    {
      "name": "feature_analyzer",
      "tokenizer": "standard",
      "tokenFilters": ["lowercase", "feature_synonyms"]
    },
    {
      "name": "tag_analyzer",
      "tokenizer": "keyword",
      "tokenFilters": ["lowercase"]
    },
    {
      "name": "autocomplete_analyzer",
      "tokenizer": "autocomplete_tokenizer",
      "tokenFilters": ["lowercase"]
    },
    {
      "name": "autocomplete_search_analyzer",
      "tokenizer": "standard",
      "tokenFilters": ["lowercase"]
    }
  ],
  "tokenizers": [
    {
      "name": "autocomplete_tokenizer",
      "@odata.type": "#Microsoft.Azure.Search.EdgeNGramTokenizer",
      "minGram": 2,
      "maxGram": 25,
      "tokenChars": ["letter", "digit"]
    }
  ],
  "tokenFilters": [
    {
      "name": "product_synonyms",
      "@odata.type": "#Microsoft.Azure.Search.SynonymTokenFilter",
      "synonyms": [
        "laptop,notebook,computer,pc",
        "phone,mobile,smartphone,cell",
        "tv,television,monitor,display",
        "headphones,earphones,earbuds,headset",
        "tablet,ipad,slate",
        "watch,smartwatch,wearable",
        "camera,camcorder,webcam",
        "speaker,audio,sound"
      ]
    },
    {
      "name": "brand_synonyms",
      "@odata.type": "#Microsoft.Azure.Search.SynonymTokenFilter",
      "synonyms": [
        "apple,mac,macbook,iphone,ipad",
        "microsoft,surface,xbox",
        "google,pixel,nest",
        "amazon,kindle,echo,alexa",
        "samsung,galaxy"
      ]
    },
    {
      "name": "category_synonyms",
      "@odata.type": "#Microsoft.Azure.Search.SynonymTokenFilter",
      "synonyms": [
        "electronics,tech,technology,gadgets",
        "computers,laptops,desktops,pcs",
        "phones,mobiles,smartphones,cells",
        "audio,sound,music,speakers,headphones",
        "gaming,games,console,xbox,playstation"
      ]
    },
    {
      "name": "feature_synonyms",
      "@odata.type": "#Microsoft.Azure.Search.SynonymTokenFilter",
      "synonyms": [
        "wireless,bluetooth,wifi,cordless",
        "waterproof,water-resistant,splash-proof",
        "fast,quick,rapid,speedy",
        "portable,compact,lightweight,mobile",
        "professional,pro,premium,advanced"
      ]
    },
    {
      "name": "english_stopwords",
      "@odata.type": "#Microsoft.Azure.Search.StopwordsTokenFilter",
      "stopwords": ["the", "and", "or", "but", "in", "on", "at", "to", "for", "of", "with", "by"]
    }
  ],
  "charFilters": [
    {
      "name": "html_strip",
      "@odata.type": "#Microsoft.Azure.Search.HtmlStripCharFilter"
    }
  ],
  "scoringProfiles": [
    {
      "name": "ecommerce_relevance",
      "text": {
        "weights": {
          "name": 5.0,
          "brand": 4.0,
          "category": 3.0,
          "description": 1.0,
          "features": 2.0,
          "tags": 2.5
        }
      },
      "functions": [
        {
          "type": "magnitude",
          "fieldName": "rating",
          "boost": 2.0,
          "interpolation": "linear",
          "magnitude": {
            "boostingRangeStart": 3.0,
            "boostingRangeEnd": 5.0,
            "constantBoostBeyondRange": true
          }
        },
        {
          "type": "magnitude",
          "fieldName": "salesCount",
          "boost": 1.5,
          "interpolation": "logarithmic",
          "magnitude": {
            "boostingRangeStart": 1,
            "boostingRangeEnd": 10000,
            "constantBoostBeyondRange": true
          }
        },
        {
          "type": "magnitude",
          "fieldName": "reviewCount",
          "boost": 1.3,
          "interpolation": "logarithmic",
          "magnitude": {
            "boostingRangeStart": 1,
            "boostingRangeEnd": 1000,
            "constantBoostBeyondRange": true
          }
        }
      ],
      "functionAggregation": "sum"
    },
    {
      "name": "revenue_optimization",
      "text": {
        "weights": {
          "name": 4.0,
          "brand": 3.0,
          "category": 2.0,
          "description": 1.0
        }
      },
      "functions": [
        {
          "type": "magnitude",
          "fieldName": "price",
          "boost": 1.8,
          "interpolation": "linear",
          "magnitude": {
            "boostingRangeStart": 100,
            "boostingRangeEnd": 2000,
            "constantBoostBeyondRange": false
          }
        },
        {
          "type": "magnitude",
          "fieldName": "salesCount",
          "boost": 2.0,
          "interpolation": "logarithmic",
          "magnitude": {
            "boostingRangeStart": 10,
            "boostingRangeEnd": 10000
          }
        }
      ],
      "functionAggregation": "sum"
    },
    {
      "name": "new_products",
      "text": {
        "weights": {
          "name": 4.0,
          "brand": 3.0,
          "category": 2.0
        }
      },
      "functions": [
        {
          "type": "freshness",
          "fieldName": "releaseDate",
          "boost": 2.5,
          "interpolation": "linear",
          "freshness": {
            "boostingDuration": "P90D"
          }
        },
        {
          "type": "magnitude",
          "fieldName": "rating",
          "boost": 1.5,
          "interpolation": "linear",
          "magnitude": {
            "boostingRangeStart": 4.0,
            "boostingRangeEnd": 5.0
          }
        }
      ],
      "functionAggregation": "sum"
    }
  ]
}

Step 3: Create Sample Product Data

Generate realistic e-commerce product data:

[
  {
    "productId": "LAPTOP-001",
    "name": "Dell XPS 13 Laptop",
    "name_autocomplete": "Dell XPS 13 Laptop",
    "brand": "Dell",
    "category": "Laptops",
    "description": "<p>Ultra-thin <b>laptop</b> with Intel Core i7 processor, 16GB RAM, and 512GB SSD. Perfect for professionals and students.</p>",
    "features": ["Intel Core i7", "16GB RAM", "512GB SSD", "13-inch Display", "Windows 11"],
    "price": 1299.99,
    "originalPrice": 1499.99,
    "rating": 4.5,
    "reviewCount": 234,
    "salesCount": 1250,
    "inventory": 45,
    "inStock": true,
    "releaseDate": "2024-01-15T00:00:00Z",
    "tags": ["laptop", "ultrabook", "business", "portable", "premium"],
    "imageUrl": "https://example.com/images/dell-xps-13.jpg",
    "url": "https://example.com/products/dell-xps-13"
  },
  {
    "productId": "PHONE-001",
    "name": "iPhone 14 Pro",
    "name_autocomplete": "iPhone 14 Pro",
    "brand": "Apple",
    "category": "Smartphones",
    "description": "Advanced <i>smartphone</i> with A16 Bionic chip, Pro camera system, and Dynamic Island.",
    "features": ["A16 Bionic Chip", "Pro Camera System", "Dynamic Island", "5G", "iOS 16"],
    "price": 1099.99,
    "originalPrice": 1099.99,
    "rating": 4.8,
    "reviewCount": 1567,
    "salesCount": 3200,
    "inventory": 120,
    "inStock": true,
    "releaseDate": "2023-09-16T00:00:00Z",
    "tags": ["smartphone", "premium", "camera", "5g", "ios"],
    "imageUrl": "https://example.com/images/iphone-14-pro.jpg",
    "url": "https://example.com/products/iphone-14-pro"
  },
  {
    "productId": "TV-001",
    "name": "Samsung 55\" 4K Smart TV",
    "name_autocomplete": "Samsung 55\" 4K Smart TV",
    "brand": "Samsung",
    "category": "Televisions",
    "description": "4K Ultra HD <b>Smart TV</b> with HDR, built-in streaming apps, and voice control.",
    "features": ["4K Ultra HD", "HDR10+", "Smart TV", "Voice Control", "55-inch"],
    "price": 649.99,
    "originalPrice": 799.99,
    "rating": 4.3,
    "reviewCount": 892,
    "salesCount": 850,
    "inventory": 25,
    "inStock": true,
    "releaseDate": "2023-11-01T00:00:00Z",
    "tags": ["tv", "smart", "4k", "streaming", "entertainment"],
    "imageUrl": "https://example.com/images/samsung-55-4k-tv.jpg",
    "url": "https://example.com/products/samsung-55-4k-tv"
  }
]

Step 4: Implement Search Functionality

Create a comprehensive search implementation:

Python Implementation

from azure.search.documents import SearchClient
from azure.search.documents.indexes import SearchIndexClient
from azure.core.credentials import AzureKeyCredential
from typing import List, Dict, Any, Optional
import json

class EcommerceSearchEngine:
    def __init__(self, service_name: str, admin_key: str, query_key: str, index_name: str):
        self.service_name = service_name
        self.index_name = index_name
        self.endpoint = f"https://{service_name}.search.windows.net"

        self.admin_client = SearchIndexClient(
            endpoint=self.endpoint,
            credential=AzureKeyCredential(admin_key)
        )

        self.search_client = SearchClient(
            endpoint=self.endpoint,
            index_name=index_name,
            credential=AzureKeyCredential(query_key)
        )

    def search_products(self, query: str, filters: Optional[str] = None, 
                       scoring_profile: Optional[str] = None,
                       facets: Optional[List[str]] = None,
                       top: int = 20) -> Dict[str, Any]:
        """Search for products with advanced filtering and scoring."""

        search_params = {
            "search_text": query,
            "top": top,
            "include_total_count": True,
            "select": [
                "productId", "name", "brand", "category", "price", 
                "originalPrice", "rating", "reviewCount", "inStock", "imageUrl"
            ]
        }

        if filters:
            search_params["filter"] = filters

        if scoring_profile:
            search_params["scoring_profile"] = scoring_profile

        if facets:
            search_params["facets"] = facets

        try:
            results = self.search_client.search(**search_params)

            # Process results
            products = []
            facet_results = {}

            for result in results:
                product = dict(result)
                # Calculate discount percentage
                if product.get("originalPrice") and product.get("price"):
                    discount = (product["originalPrice"] - product["price"]) / product["originalPrice"] * 100
                    product["discountPercentage"] = round(discount, 1)
                products.append(product)

            # Extract facets if requested
            if hasattr(results, 'get_facets') and facets:
                facet_results = results.get_facets()

            return {
                "products": products,
                "totalCount": results.get_count() if hasattr(results, 'get_count') else len(products),
                "facets": facet_results,
                "query": query,
                "filters": filters,
                "scoringProfile": scoring_profile
            }

        except Exception as e:
            return {
                "error": str(e),
                "products": [],
                "totalCount": 0,
                "facets": {},
                "query": query
            }

    def autocomplete_products(self, partial_query: str, top: int = 10) -> List[str]:
        """Get autocomplete suggestions for product names."""

        try:
            results = self.search_client.search(
                search_text=partial_query,
                search_fields=["name_autocomplete"],
                select=["name"],
                top=top
            )

            suggestions = []
            seen = set()

            for result in results:
                name = result.get("name", "")
                if name and name not in seen:
                    suggestions.append(name)
                    seen.add(name)

            return suggestions

        except Exception as e:
            print(f"Autocomplete error: {e}")
            return []

    def get_product_recommendations(self, product_id: str, top: int = 5) -> List[Dict[str, Any]]:
        """Get product recommendations based on similar products."""

        try:
            # First, get the current product
            current_product = list(self.search_client.search(
                search_text="*",
                filter=f"productId eq '{product_id}'",
                select=["brand", "category", "price", "tags"],
                top=1
            ))

            if not current_product:
                return []

            product = current_product[0]
            brand = product.get("brand", "")
            category = product.get("category", "")
            price = product.get("price", 0)

            # Build recommendation query
            price_range_filter = f"price ge {price * 0.7} and price le {price * 1.3}"
            category_filter = f"category eq '{category}'"
            exclude_current = f"productId ne '{product_id}'"

            combined_filter = f"({price_range_filter}) and ({category_filter}) and ({exclude_current})"

            # Search for similar products
            results = self.search_client.search(
                search_text=f"{brand} {category}",
                filter=combined_filter,
                scoring_profile="ecommerce_relevance",
                select=["productId", "name", "brand", "price", "rating", "imageUrl"],
                top=top
            )

            recommendations = []
            for result in results:
                recommendations.append(dict(result))

            return recommendations

        except Exception as e:
            print(f"Recommendations error: {e}")
            return []

# Usage examples
def demonstrate_ecommerce_search():
    """Demonstrate various e-commerce search scenarios."""

    search_engine = EcommerceSearchEngine(
        "your-service", "your-admin-key", "your-query-key", "ecommerce-products"
    )

    # Test scenarios
    test_scenarios = [
        {
            "name": "Product Name Search",
            "query": "iPhone",
            "scoring_profile": "ecommerce_relevance"
        },
        {
            "name": "Category Search with Filters",
            "query": "laptop",
            "filters": "price le 1500 and inStock eq true",
            "facets": ["brand", "category", "rating"],
            "scoring_profile": "ecommerce_relevance"
        },
        {
            "name": "Feature-based Search",
            "query": "wireless headphones",
            "scoring_profile": "ecommerce_relevance"
        },
        {
            "name": "Revenue Optimization",
            "query": "smartphone",
            "scoring_profile": "revenue_optimization"
        },
        {
            "name": "New Products Promotion",
            "query": "laptop",
            "scoring_profile": "new_products"
        }
    ]

    for scenario in test_scenarios:
        print(f"\n{'='*60}")
        print(f"Scenario: {scenario['name']}")
        print(f"Query: {scenario['query']}")
        if scenario.get('filters'):
            print(f"Filters: {scenario['filters']}")
        print(f"{'='*60}")

        results = search_engine.search_products(**scenario)

        if results.get("error"):
            print(f"Error: {results['error']}")
            continue

        print(f"Total Results: {results['totalCount']}")

        for i, product in enumerate(results["products"][:5], 1):
            name = product.get("name", "Unknown")
            brand = product.get("brand", "Unknown")
            price = product.get("price", 0)
            rating = product.get("rating", 0)
            score = product.get("@search.score", 0)

            print(f"{i}. {name} ({brand})")
            print(f"   Price: ${price:.2f}, Rating: {rating}, Score: {score:.3f}")

        # Show facets if available
        if results.get("facets"):
            print(f"\nFacets:")
            for facet_name, facet_values in results["facets"].items():
                print(f"  {facet_name}:")
                for facet in facet_values[:3]:  # Show top 3
                    print(f"    {facet['value']} ({facet['count']})")

    # Test autocomplete
    print(f"\n{'='*60}")
    print("Autocomplete Testing")
    print(f"{'='*60}")

    autocomplete_queries = ["iph", "lap", "sam"]
    for query in autocomplete_queries:
        suggestions = search_engine.autocomplete_products(query)
        print(f"'{query}' -> {suggestions}")

Step 5: Implement Business Logic

Add business-specific search logic:

class BusinessLogicEngine:
    def __init__(self, search_engine: EcommerceSearchEngine):
        self.search_engine = search_engine

    def search_with_business_rules(self, query: str, user_context: Dict[str, Any]) -> Dict[str, Any]:
        """Apply business rules to search results."""

        # Determine scoring profile based on business goals
        scoring_profile = self._select_scoring_profile(user_context)

        # Build filters based on business rules
        filters = self._build_business_filters(user_context)

        # Execute search
        results = self.search_engine.search_products(
            query=query,
            filters=filters,
            scoring_profile=scoring_profile,
            facets=["brand", "category", "price", "rating"]
        )

        # Apply post-processing business rules
        results["products"] = self._apply_post_processing_rules(results["products"], user_context)

        return results

    def _select_scoring_profile(self, user_context: Dict[str, Any]) -> str:
        """Select appropriate scoring profile based on business context."""

        # Revenue optimization for high-value customers
        if user_context.get("customer_tier") == "premium":
            return "revenue_optimization"

        # New product promotion during launch periods
        if user_context.get("promotion_active"):
            return "new_products"

        # Default relevance-based scoring
        return "ecommerce_relevance"

    def _build_business_filters(self, user_context: Dict[str, Any]) -> Optional[str]:
        """Build filters based on business rules."""

        filters = []

        # Always show in-stock items first
        filters.append("inStock eq true")

        # Apply price range based on user segment
        if user_context.get("price_range"):
            min_price, max_price = user_context["price_range"]
            filters.append(f"price ge {min_price} and price le {max_price}")

        # Filter by user's preferred brands
        if user_context.get("preferred_brands"):
            brand_filter = " or ".join([f"brand eq '{brand}'" for brand in user_context["preferred_brands"]])
            filters.append(f"({brand_filter})")

        return " and ".join(filters) if filters else None

    def _apply_post_processing_rules(self, products: List[Dict[str, Any]], 
                                   user_context: Dict[str, Any]) -> List[Dict[str, Any]]:
        """Apply business rules to search results."""

        # Add business metadata
        for product in products:
            # Calculate profit margin indicator
            original_price = product.get("originalPrice", product.get("price", 0))
            current_price = product.get("price", 0)
            if original_price > current_price:
                product["onSale"] = True
                product["discountPercentage"] = round((original_price - current_price) / original_price * 100, 1)

            # Add inventory urgency
            inventory = product.get("inventory", 0)
            if inventory < 10:
                product["lowStock"] = True

            # Add personalization signals
            if user_context.get("purchase_history"):
                # Check if user has bought from this brand before
                user_brands = [item["brand"] for item in user_context["purchase_history"]]
                if product.get("brand") in user_brands:
                    product["previouslyPurchasedBrand"] = True

        return products

# Usage example
def demonstrate_business_logic():
    """Demonstrate business logic integration."""

    search_engine = EcommerceSearchEngine(
        "your-service", "your-admin-key", "your-query-key", "ecommerce-products"
    )

    business_engine = BusinessLogicEngine(search_engine)

    # Test different user contexts
    user_contexts = [
        {
            "name": "Premium Customer",
            "customer_tier": "premium",
            "price_range": (500, 2000),
            "preferred_brands": ["Apple", "Samsung"]
        },
        {
            "name": "Budget-Conscious User",
            "price_range": (0, 500),
            "promotion_active": True
        },
        {
            "name": "Returning Customer",
            "purchase_history": [
                {"brand": "Dell", "category": "Laptops"},
                {"brand": "Apple", "category": "Smartphones"}
            ]
        }
    ]

    query = "laptop"

    for context in user_contexts:
        print(f"\n{'='*60}")
        print(f"User Context: {context['name']}")
        print(f"{'='*60}")

        results = business_engine.search_with_business_rules(query, context)

        print(f"Total Results: {results['totalCount']}")
        print(f"Scoring Profile: {results.get('scoringProfile', 'default')}")
        print(f"Filters Applied: {results.get('filters', 'none')}")

        for i, product in enumerate(results["products"][:3], 1):
            name = product.get("name", "Unknown")
            brand = product.get("brand", "Unknown")
            price = product.get("price", 0)

            print(f"{i}. {name} ({brand}) - ${price:.2f}")

            # Show business metadata
            if product.get("onSale"):
                print(f"   🏷️ On Sale: {product.get('discountPercentage', 0)}% off")
            if product.get("lowStock"):
                print(f"   ⚠️ Low Stock")
            if product.get("previouslyPurchasedBrand"):
                print(f"   👤 Previously purchased brand")

✅ Validation

Performance Metrics

Measure and validate your e-commerce search system:

  1. Search Relevance
  2. Click-through rates on search results
  3. Conversion rates from search to purchase
  4. User satisfaction scores

  5. Business Impact

  6. Revenue per search session
  7. Average order value from search
  8. Product discovery rates

  9. Technical Performance

  10. Search latency (target: <100ms)
  11. Indexing throughput
  12. System availability

Test Cases

Create comprehensive test cases:

def validate_ecommerce_search():
    """Validate e-commerce search functionality."""

    test_cases = [
        {
            "name": "Exact Product Match",
            "query": "iPhone 14 Pro",
            "expected_first_result": "iPhone 14 Pro",
            "scoring_profile": "ecommerce_relevance"
        },
        {
            "name": "Category Search",
            "query": "laptops",
            "expected_category": "Laptops",
            "min_results": 1
        },
        {
            "name": "Synonym Expansion",
            "query": "notebook",
            "should_find": "laptop",
            "scoring_profile": "ecommerce_relevance"
        },
        {
            "name": "Revenue Optimization",
            "query": "smartphone",
            "scoring_profile": "revenue_optimization",
            "expected_behavior": "Higher priced items should rank higher"
        }
    ]

    search_engine = EcommerceSearchEngine(
        "your-service", "your-admin-key", "your-query-key", "ecommerce-products"
    )

    passed = 0
    failed = 0

    for test_case in test_cases:
        print(f"\nTesting: {test_case['name']}")

        results = search_engine.search_products(
            query=test_case["query"],
            scoring_profile=test_case.get("scoring_profile"),
            top=10
        )

        if results.get("error"):
            print(f"  ❌ FAIL: {results['error']}")
            failed += 1
            continue

        products = results["products"]

        # Validate based on test case criteria
        success = True

        if test_case.get("expected_first_result"):
            if not products or test_case["expected_first_result"] not in products[0].get("name", ""):
                print(f"  ❌ FAIL: Expected '{test_case['expected_first_result']}' as first result")
                success = False

        if test_case.get("min_results"):
            if len(products) < test_case["min_results"]:
                print(f"  ❌ FAIL: Expected at least {test_case['min_results']} results, got {len(products)}")
                success = False

        if test_case.get("should_find"):
            found = any(test_case["should_find"].lower() in product.get("name", "").lower() 
                       for product in products)
            if not found:
                print(f"  ❌ FAIL: Should find products containing '{test_case['should_find']}'")
                success = False

        if success:
            print(f"  ✅ PASS")
            passed += 1
        else:
            failed += 1

    print(f"\nValidation Results: {passed} passed, {failed} failed")
    return failed == 0

🚀 Extensions

Extension 1: A/B Testing Framework

Implement A/B testing to compare different scoring profiles and measure business impact.

Extension 2: Real-time Personalization

Add real-time personalization based on user behavior, browsing history, and preferences.

Extension 3: Advanced Analytics

Implement search analytics to track query patterns, result clicks, and conversion funnels.

Extension 4: Mobile Optimization

Optimize the search experience for mobile devices with different UI patterns and performance requirements.

Extension 5: Voice Search Integration

Add voice search capabilities with natural language processing and speech-to-text integration.

💡 Solutions

Key Implementation Insights

  1. Analyzer Strategy:
  2. Use domain-specific synonyms for product categories
  3. Implement separate analyzers for different field types
  4. Balance search recall with precision

  5. Scoring Profile Design:

  6. Align scoring with business objectives (revenue, conversion)
  7. Use multiple profiles for different scenarios
  8. Test and iterate based on real user behavior

  9. Performance Optimization:

  10. Use selective field analysis
  11. Implement caching for common queries
  12. Monitor and optimize based on usage patterns

Business Impact Measurement

Track these KPIs to measure success:

  • Search Conversion Rate: Percentage of searches leading to purchases
  • Revenue per Search: Average revenue generated per search session
  • Search Abandonment Rate: Percentage of searches with no clicks
  • Time to Purchase: Average time from search to purchase
  • Product Discovery Rate: Percentage of products found through search

Next Exercise: Multi-language Content Analysis - Handle diverse, multilingual e-commerce content.