Table of contents :

Keeping WooCommerce and Weaviate in Sync

100-days-of-weaviate-013

Table of contents :

WooCommerce is the system of record for catalog, pricing, inventory, and publication status. Weaviate is the retrieval layer that makes that information searchable by meaning. Keeping both systems synchronized requires more than sending a product to Weaviate once. A production integration must handle updates, deletions, failed requests, retries, variation data, and changes to the content used for vectorization.

Define the ownership boundary first

Before implementing synchronization, decide which system owns each field. WooCommerce should normally remain authoritative for transactional and catalog data, including:

  • Product and variation identifiers
  • Names, descriptions, attributes, categories, and tags
  • Prices, stock quantities, and stock status
  • Publication status and visibility
  • Product images and external URLs

Weaviate should store the fields needed for semantic search, recommendations, or retrieval-augmented applications. It can also store denormalized values such as a searchable category name or a formatted price range, but those values should be rebuilt from WooCommerce rather than edited independently.

This boundary prevents a common failure mode: a merchandising change is made in WooCommerce, while an application continues serving stale values from Weaviate because nobody knows which system is authoritative.

Use a stable identity for every object

Do not use the product name, slug, or generated vector as the synchronization key. Names and slugs can change, and vectors are recalculated whenever source content changes. Store the WooCommerce product ID as a property such as woocommerce_product_id and use it to construct a deterministic application-level identity.

For stores with variations, give each variation its own identity. A practical key might combine the product and variation IDs:

{
  "woocommerce_product_id": 1842,
  "woocommerce_variation_id": 1871,
  "source_type": "variation"
}

Whether products and variations belong to one Weaviate collection or separate collections depends on the search experience. A single collection simplifies queries across all purchasable items. Separate collections can be useful when product-level and variation-level results require different properties or ranking rules. The important point is that the mapping remains deterministic and documented.

Capture changes with WooCommerce hooks and webhooks

A scheduled full export is useful for initial loading and reconciliation, but it is not a reliable primary synchronization mechanism. Use WooCommerce and WordPress events to create change messages as soon as catalog data changes.

Common events include product creation, product updates, status changes, stock changes, price changes, and deletion or trash actions. The exact hooks depend on the type of change and the plugins installed on the site. For example, a product save event can trigger a complete reindex of one product, while stock-specific hooks can trigger a smaller update when only inventory has changed.

For integrations that should remain loosely coupled to WordPress, WooCommerce webhooks can deliver product events to an external synchronization service. For an integration implemented inside WordPress, action hooks can enqueue the same kind of message locally.

The event handler should do as little work as possible. It should record an event or enqueue a job, not make a slow remote vector database request during the administrator’s save request.

<?php
add_action('save_post_product', function ($post_id, $post, $update) {
    if (wp_is_post_revision($post_id) || $post->post_status === 'auto-draft') {
        return;
    }

    // Persist an idempotent synchronization job for a worker to process.
    my_queue_product_sync((int) $post_id);
}, 10, 3);

The example is intentionally minimal. A production implementation should also check permissions, avoid processing unsupported post types, and account for product variations and updates made by bulk editors or import plugins.

Prefer an outbox or durable queue

WordPress hooks run inside a request that can fail, time out, or be rolled back. Sending directly to Weaviate from the hook creates a reliability gap: the WooCommerce update may succeed while the outbound request fails.

An outbox pattern closes that gap. When a product changes, write a synchronization record to a durable store with the product ID, event type, source version, and attempt metadata. A worker then claims pending records and sends them to Weaviate. Action Scheduler, a hosted queue, or a message broker can all work, provided jobs survive PHP process failures and can be retried.

Coalesce repeated updates where possible. If a product is edited five times before a worker runs, processing the latest state once is usually better than sending five intermediate versions. Keep the event timestamp or source version so an older job cannot overwrite a newer representation.

Make writes idempotent

Retries are inevitable when the network, Weaviate, or the worker process is unavailable. A retry must produce the same final state as a single successful attempt. Use deterministic object identifiers or look up the object by the WooCommerce ID before updating it. Avoid an unconditional create operation that produces duplicates after a timeout.

A synchronization worker should generally follow this sequence:

  1. Load the current product and variation data from WooCommerce.
  2. Check whether the item is eligible for indexing.
  3. Build a normalized Weaviate payload.
  4. Create or replace the corresponding object using its stable identity.
  5. Record the source version, synchronization time, and result.

For partial changes, an update can be efficient, but a complete replacement is often safer when the indexed document is assembled from many WooCommerce fields. It prevents removed categories, attributes, or old text from remaining in Weaviate.

Build a deliberate searchable document

Do not blindly copy every WooCommerce field into Weaviate. Decide what customers are expected to search for and create a consistent representation. A product document might contain properties such as:

{
  "woocommerce_product_id": 1842,
  "woocommerce_variation_id": null,
  "name": "Waterproof hiking jacket",
  "description": "Lightweight shell for wet-weather trail use.",
  "categories": ["Outdoor clothing", "Jackets"],
  "attributes": ["Colour: Green", "Size: Medium"],
  "sku": "JACKET-GRN-M",
  "price": 129.00,
  "currency": "GBP",
  "stock_status": "instock",
  "catalog_visibility": "visible",
  "source_updated_at": "2025-01-15T10:30:00Z"
}

Normalize HTML descriptions before indexing. Remove navigation fragments, repeated shortcodes, tracking parameters, and irrelevant layout text. Preserve useful headings, materials, dimensions, compatibility information, and other language that improves retrieval.

Whether price and stock should be embedded in the vectorized text depends on the application. Frequently changing values can create unnecessary re-vectorization. A useful pattern is to use Weaviate for semantic relevance and apply current stock or price constraints as filters, or validate those values against WooCommerce immediately before displaying an offer.

Separate content changes from operational changes

Not every WooCommerce update requires the same synchronization work. A description or category change normally requires the searchable properties and vector to be refreshed. A stock quantity change may only require a scalar property update. A price change may require a property update and cache invalidation without changing the vector.

Classify events into at least three groups:

  • Representation changes: name, description, attributes, categories, or images used in searchable content. Rebuild the object and vector.
  • Filter changes: price, stock status, visibility, or availability dates. Update filterable properties and consider whether re-vectorization is necessary.
  • Lifecycle changes: publication, trash, deletion, or restoration. Create, deactivate, or remove the Weaviate object according to the catalog policy.

This classification reduces embedding costs while keeping customer-facing filters current.

Handle deletion and visibility explicitly

Deleting a WordPress post, moving a product to the trash, setting it to draft, or changing catalog visibility can all make an item unsuitable for search. Do not assume that a missing item in a later export will automatically disappear from Weaviate.

Choose one policy and apply it consistently:

  • Delete the Weaviate object when the product is permanently removed or no longer eligible for discovery.
  • Keep the object but set is_searchable to false when auditability or restoration is important.
  • Use filters for publication status, stock status, or sales-channel visibility where the application requires those distinctions.

Soft deletion is often useful for debugging, but the search layer must apply the visibility filter on every relevant query. Otherwise, a draft or discontinued product can still appear in results.

Protect against out-of-order events

Queues and retries can deliver events out of order. An update generated at 12:05 may arrive before an update generated at 12:03. Include a source timestamp, revision number, or another monotonic value in each synchronization message. The worker should reject an older message when a newer source version has already been applied.

When no reliable revision number is available, reload the current product from WooCommerce at processing time and treat the queue message as a signal to synchronize rather than as the complete source payload. This approach makes the final state reflect the current catalog, even when intermediate events were delayed.

Reconcile continuously

Event-driven synchronization should be combined with reconciliation. A scheduled job can compare eligible WooCommerce IDs with the IDs stored in Weaviate, identify missing objects, detect stale timestamps, and remove orphaned records.

For large catalogs, reconcile in pages and avoid loading the entire catalog into PHP memory. Record metrics such as pending jobs, synchronization age, failed attempts, missing objects, duplicate identities, and deletion count. Alert when the oldest pending job exceeds the business tolerance for stale search results.

A useful operational test is to select a sample of products and compare the WooCommerce source payload with the corresponding Weaviate properties. Check both positive cases, such as a newly published product appearing in search, and negative cases, such as a trashed product no longer being returned.

Plan for bulk imports and reindexing

Product import plugins and marketplace feeds can update thousands of records in a short period. Avoid creating one synchronous remote request per database save. Batch the resulting jobs, limit worker concurrency, and use Weaviate’s batch facilities where appropriate. Batch size should be measured against payload size, request limits, memory use, and the time required to retry a failed batch.

Keep a reindex command that can rebuild one product, a product range, a category, or the entire catalog. It should support a dry-run mode, progress reporting, resumable checkpoints, and a way to rebuild only documents whose source content or schema version has changed.

When the indexed representation changes, store an application-level document_schema_version. A version change gives the worker a clear way to identify objects that need rebuilding, even when the WooCommerce product itself has not changed.

Use Weaviate for discovery and WooCommerce for final truth

Semantic search results can become stale between synchronization and checkout. Before displaying an actionable price or allowing an add-to-cart operation, validate the product, variation, stock, and current price against WooCommerce or the store’s established commerce API.

This division keeps the search experience fast without allowing an outdated vector database document to become the authority for a purchase. The result from Weaviate identifies relevant products; WooCommerce confirms that the selected item is still published, purchasable, correctly priced, and available.

Minimum production checklist

  • Use WooCommerce as the source of truth for catalog and commerce fields.
  • Store stable product and variation identifiers in Weaviate.
  • Enqueue changes instead of performing remote synchronization in save requests.
  • Make create, update, retry, and delete operations idempotent.
  • Protect against out-of-order messages with source versions or current-state reloads.
  • Separate vector-requiring content changes from scalar stock and price changes.
  • Filter unpublished, hidden, and discontinued products consistently.
  • Run scheduled reconciliation and expose synchronization metrics.
  • Support targeted and full reindexing with a document schema version.
  • Validate current commerce data in WooCommerce before checkout or add to cart.
Trending posts
You might also like