Skip to main content

Overview

The Search API provides fast, flexible product search using Dgraph’s graph database capabilities. It supports custom queries for product search, related products, and complex relationship-based filtering.

Endpoints

POST /api/v2/search
Executes a custom Dgraph query for product search.
POST /api/v2/related-products
Finds related products based on relationships and attributes.

Dgraph Integration

The search functionality uses Dgraph, a native graph database that enables complex queries with predicates and filters.

Connection Configuration

from settings import DGRAPH_SERVER_CLIENT
import pydgraph

client_stub = pydgraph.DgraphClientStub(DGRAPH_SERVER_CLIENT)
client = pydgraph.DgraphClient(client_stub)
Queries are executed with:
  • Read-only transactions for safety
  • Best-effort mode for improved performance
  • 1-second timeout for fast responses
  • Long-term caching via Beaker

Query Format

Send Dgraph queries as JSON in the request body:
{
  "query": "{
    search(func: type(Product)) @filter(eq(status, 1)) {
      uid
      product_id
      name
      price
      spl_price
      images
      category {
        name
      }
    }
  }"
}

Search Examples

Search Products by Name

{
  products(func: type(Product)) @filter(regexp(name, /tshirt/i)) {
    uid
    product_id
    name
    price
    spl_price
    sale_url
    images
  }
}

Search with Category Filter

{
  products(func: type(Product)) @cascade {
    uid
    product_id
    name
    price
    category @filter(eq(category_id, 123)) {
      category_id
      name
    }
  }
}

Search by Price Range

{
  products(func: type(Product)) @filter(ge(spl_price, 500) AND le(spl_price, 2000)) {
    uid
    product_id
    name
    price
    spl_price
    images
  }
}

Search with Multiple Filters

{
  products(func: type(Product)) @filter(
    eq(status, 1) AND 
    ge(spl_price, 500) AND 
    regexp(name, /premium/i)
  ) {
    uid
    product_id
    name
    price
    spl_price
    category {
      name
    }
    tags {
      name
    }
  }
}
Find products related by category, tags, or artist:
{
  "query": "{
    var(func: uid(0x123)) {
      category {
        ~category @filter(type(Product)) {
          related as uid
        }
      }
    }
    related(func: uid(related), first: 10) {
      uid
      product_id
      name
      price
      images
    }
  }"
}

Data Model

Products in Dgraph have the following key predicates:
product_id
integer
required
Unique product identifier from MySQL
name
string
required
Product name
price
float
Regular price
spl_price
float
Special/sale price
status
integer
Product status (1 = active, 0 = inactive)
category
[uid]
References to category nodes
tags
[uid]
References to tag nodes
variants
[uid]
References to variant nodes
pricelists
[uid]
References to pricelist nodes for exclusive pricing

Caching

Search queries are cached using Beaker’s long-term cache region:
@cache_region('long_term', 'search')
def query_dgraph(query):
    # Execute query with caching
Cache key is generated from the query string. Cache duration is configured in your cache settings.

Performance Optimization

For optimal search performance:
  1. Use specific filters to reduce result set size
  2. Leverage indexed predicates (product_id, status, price)
  3. Use first: N to limit results
  4. Enable best-effort transactions for read-only queries
  5. Cache frequently-used queries

Data Synchronization

Products are synced to Dgraph via Celery background tasks:
# Sync product to Dgraph
@app.task
def syncDgraphProduct(product_ids):
    sync_product = SyncProduct()
    sync_product.product_ids = product_ids
    sync_product.make_product_categories()
    sync_product.make_product_tags()
    sync_product.make_product_variants()
    sync_product.set_payload()
    sync_product.insert_into_dgraph()
See tasks.py:111 for the complete implementation.

Elasticsearch Alternative

While Dgraph is the primary search engine, the system also supports Elasticsearch:
SEARCH_ENDPOINT = os.environ.get('SEARCH_ENDPOINT')
ELASTIC_SEARCH_HOST = os.environ.get('ELASTIC_SEARCH_HOST')
Elasticsearch is used for:
  • Full-text product search
  • User widget data indexing
  • Visit logging and analytics

Error Handling

The search API handles errors gracefully:
{
  "status": "error",
  "message": "Exception in query_dgraph: connection refused"
}
Common errors:
  • Connection timeout - Dgraph server unreachable
  • Query syntax error - Invalid Dgraph query format
  • Empty result - Query matched no nodes
Queries have a 1-second timeout (see DgraphController.py:17). Complex queries may need optimization to complete within this limit.

Advanced Queries

{
  var(func: type(Product)) @filter(eq(status, 1)) {
    uid
  }
  
  categories(func: uid(var)) @groupby(category) {
    count(uid)
  }
  
  tags(func: uid(var)) @groupby(tags) {
    count(uid)
  }
}

Aggregate Queries

{
  products(func: type(Product)) @filter(eq(category_id, 123)) {
    avg_price: avg(spl_price)
    min_price: min(spl_price)
    max_price: max(spl_price)
    count: count(uid)
  }
}

GraphQL API

Alternative querying method for product data

Celery Tasks

Background sync operations for search indexing

Build docs developers (and LLMs) love