Thuta Learning
BasicData & Databasesbeginner

The Core Data Model — Indices, Documents, and Mapping

What you'll walk away with

  • Explain the core ideas behind The Core Data Model — Indices, Documents, and Mapping
  • Run the sample Elasticsearch query or code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

In Elasticsearch, an index is roughly analogous to a PostgreSQL table: it is a container of similarly structured JSON documents — a `tutorials` index might hold every tutorial document. Each document is a JSON object with a unique `_id`, and unlike a PostgreSQL row, a document can naturally hold nested objects and arrays of objects without needing a join table. Mapping is the schema-like definition that declares each field's data type (text, keyword, integer, date, and so on) within an index, serving the same purpose as `CREATE TABLE` column definitions in PostgreSQL. A real difference from PostgreSQL, though, is that if you don't specify a mapping explicitly, Elasticsearch's dynamic mapping auto-detects field types — convenient for quick prototyping, but risky in production because the auto-detected type may not be the one you actually wanted (for example, a `price` field silently detected as a string). Think of mapping like a screenplay's script format: just as a script format tells a reader how to parse each element (dialogue, action, scene heading), mapping tells Elasticsearch how to index and search each field.

Connect it to a real scenario

Design the Tutorial Platform search index as `tutorials`, where each document has `title`, `body`, `tags` (an array), `authorName`, `publishedAt`, and `difficulty` fields. Define an explicit mapping — `title` as `text` for full-text search, `tags` as `keyword` for exact filtering and facets, and `publishedAt` as `date` — rather than trusting dynamic mapping to guess correctly. When a row from PostgreSQL's `tutorials` table becomes an Elasticsearch document, flatten related rows from the `lessons` table into a single nested array inside that document, so no join is needed at search time.

Try the working example

json
PUT /tutorials
{
  "mappings": {
    "properties": {
      "title":       { "type": "text" },
      "body":        { "type": "text" },
      "tags":        { "type": "keyword" },
      "authorName":  { "type": "keyword" },
      "publishedAt": { "type": "date" },
      "difficulty":  { "type": "keyword" }
    }
  }
}
You should see
You can create a `tutorials` index with an explicit mapping.

5-minute try-it

Write a mapping for a `comments` index with `body` (text), `authorId` (keyword), `createdAt` (date), and `upvotes` (integer) fields.

One important caution

Skipping an explicit mapping and letting dynamic mapping guess field types — a `tags` field auto-detected as `text` instead of `keyword` breaks exact-match filtering.

Copying the PostgreSQL row structure directly instead of denormalizing related table data (like lessons) into a nested array — every search query then needs join-like logic again.

Elasticsearch Guide — Documents and IndicesElastic

Easy traps

  • Skipping an explicit mapping and letting dynamic mapping guess field types — a `tags` field auto-detected as `text` instead of `keyword` breaks exact-match filtering.
  • Copying the PostgreSQL row structure directly instead of denormalizing related table data (like lessons) into a nested array — every search query then needs join-like logic again.
  • Validate sample queries and requests on a local or test instance with recoverable data before applying them to production.

Exercise

Write a mapping for a `comments` index with `body` (text), `authorId` (keyword), `createdAt` (date), and `upvotes` (integer) fields.

You'll know it worked when: You can create a `tutorials` index with an explicit mapping.

The Core Data Model — Indices, Documents, and Mapping | Thuta Learning