Does DynamoDB support full-text search?

No, not natively. DynamoDB has no full-text search: no relevance ranking, no stemming, and no fuzzy matching — the built-in string tools are exact comparisons, begins_with on sort keys, and contains substring filters. AWS's answer is the zero-ETL integration with Amazon OpenSearch Service, which replicates a table into a search index for full-text, vector, and semantic search.

What you can do natively

  • begins_with on a sort key — efficient prefix matching inside one partition; the backbone of hierarchical sort-key models.
  • contains in a filter expression — substring matching, but filters run after the read, so on a Scan you still pay to read every item examined. See the filtering strategies guide for when this is acceptable.

Neither ranks results, tolerates typos, or understands word boundaries — they are string predicates, not search.

The same query, four ways, measured

We loaded 100 items (84 KB) with product titles and scanned the table four times, changing only the search term:

FilterCountScannedCountRead unitsMatched
contains(title, "run")310011Shoes for runs · Trail running shoe · Sneaker, runner grade
contains(title, "Run")210011Running shoes · Rungs for a ladder
contains(title, "running")110011Trail running shoe
contains(title, "runing")010011nothing

Read those rows as a user typing into a box would. "run" misses Running shoes and RUNNING SHORTS, because the comparison is case-sensitive. "Run" recovers Running shoes, still misses RUNNING SHORTS, and drags in Rungs for a ladder, because a substring has no idea where a word begins. No casing of that query finds all three. Drop a letter and you get nothing at all, since there is no fuzzy fallback to degrade to.

The last column is the part that costs money. Every scan consumed 11 read units, including the one that matched nothing, because the filter runs after the read. AWS says so plainly: "A filter expression is applied after a Scan finishes but before the results are returned. Therefore, a Scan consumes the same amount of read capacity, regardless of whether a filter expression is present." Their own diagnosis of the shape above: "A high ScannedCount value with few, or no, Count results indicates an inefficient Scan operation."

So the price of a search tracks the size of the catalog, never the specificity of the query. Wire this to a search-as-you-type box and "running shoes" bills the whole table thirteen times, once per keystroke, to return one item.

The AWS-native answer: zero-ETL to OpenSearch

The DynamoDB plugin for OpenSearch Ingestion syncs a table into one or more OpenSearch indexes: an initial snapshot loads via DynamoDB's S3 export (PITR required), then DynamoDB Streams replicates changes in near real time. The pipeline consumes none of your table's read or write throughput, so it's safe next to production traffic — and AWS states the integration enables full-text, vector, and semantic search over your DynamoDB data.

Go deeper

If your "search" is really a known lookup, fix the model instead — the filtering strategies and sort key strategies guides show what keys can do. Prototype begins_with/contains conditions in the expression builder, and download DynoTable to filter live table data as you explore.

References

Last verified 2026-07-13 against the official AWS documentation linked above.

The four scans were run 2026-07-28 against DynamoDB Local 3.3.0 with @aws-sdk/client-dynamodb 3.1095.0 on Node v24.18.0. Count, ScannedCount and the read units are the engine's own numbers.

Work with DynamoDB without the Console

A fast DynamoDB desktop client that runs the real SQL DynamoDB can’t — JOINs, GROUP BY, aggregates — with visual editing and an AI agent on your own Bedrock keys.

Free 30-day trial, no credit card — then the Free plan with no time limit.