PrepZone Logo
PrepZone

Elasticsearch CRUD and Mapping

Index documents, dynamic vs explicit mapping, and keyword vs text fields.

Why this matters

  • VaultCommerce product SKUs must be keyword (exact match, aggregations); descriptions must be text (analyzed for search). Swapping them breaks faceted filters and full-text queries.
  • Bulk indexing during catalog sync needs the _bulk API — single-document PUTs cannot keep up with nightly imports.
  • Mapping mistakes (e.g., price mapped as text) require reindex — expensive at millions of documents.
Cluster
Node 1Shard 0 primary
Node 2Shard 1 primary
Node 3Shard 0 replica
An index is split into shards across nodes. Replicas provide failover and read scaling.

Explicit mapping for products

Java
curl -X PUT "localhost:9200/vaultcommerce-products" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "sku":        { "type": "keyword" },
      "title":      { "type": "text", "fields": { "raw": { "type": "keyword" } } },
      "description":{ "type": "text" },
      "category":   { "type": "keyword" },
      "price":      { "type": "float" },
      "in_stock":   { "type": "boolean" },
      "tags":       { "type": "keyword" }
    }
  }
}'

keyword vs text

  • keyword — stored as-is for filters, sorting, aggregations (SKU, category).
  • text — analyzed (tokenized, lowercased) for full-text search (title, description).
  • Multi-fields — title.raw keyword sub-field for exact sort while title remains searchable.

Dynamic mapping works for prototypes; VaultCommerce locks mapping before production indexing.

CRUD operations

Java
# Create (index)
PUT /vaultcommerce-products/_doc/SKU-8842
{"sku":"SKU-8842","title":"Trail Pack 40L","price":89.0,"category":"outdoor"}

# Read
GET /vaultcommerce-products/_doc/SKU-8842

# Partial update
POST /vaultcommerce-products/_update/SKU-8842
{"doc":{"price":79.0,"in_stock":true}}

# Delete
DELETE /vaultcommerce-products/_doc/SKU-8842
Java
from elasticsearch import Elasticsearch

es = Elasticsearch("http://localhost:9200")

doc = {"sku": "SKU-8842", "title": "Trail Pack 40L", "price": 89.0}
es.index(index="vaultcommerce-products", id="SKU-8842", document=doc)
hit = es.get(index="vaultcommerce-products", id="SKU-8842")
es.update(index="vaultcommerce-products", id="SKU-8842", doc={"price": 79.0})

Bulk import for catalog sync

Java
POST /_bulk
{ "index": { "_index": "vaultcommerce-products", "_id": "SKU-8842" } }
{ "sku": "SKU-8842", "title": "Trail Pack 40L", "price": 89.0 }
{ "index": { "_index": "vaultcommerce-products", "_id": "SKU-3310" } }
{ "sku": "SKU-3310", "title": "Summit Tent", "price": 249.0 }

Use bulk batches of 1,000–5,000 documents with refresh=false during large imports, then force refresh once.

Quick recall

Everything you need if you only revisit this box.

  • Mapping defines field types — keyword for exact match, text for analyzed search.
  • CRUD: index (PUT/POST), get, update (_update), delete — documents are JSON.
  • VaultCommerce maps SKU/category as keyword, title/description as text.
  • Bulk _bulk API is mandatory for large catalog imports.
  • Explicit mapping beats dynamic guessing — mistakes require reindex.
  • Multi-fields (title.raw) support both search and exact sort.

Test yourself

Answer these before moving on — recall is what makes it stick.