accesspatterns.dev

You can only filter on what you declared

A vector index will only filter on attributes you nominated when you created it, with = and nothing else.

Why

Three of the four examples here are refusals, and each one is refused for a different reason. Try them in order. A vector index will only filter on attributes you nominated when you created it, and only with equals, and it says no immediately rather than quietly reading more rows.

You have met this shape before. A GSI makes you choose its key up front, and a Query that does not use that key cannot run against it. A vector index asks for more: the attribute it partitions by, and every attribute you might later want to filter on, all decided at creation and none of them addable afterwards.

Those choices live in the SearchSchema. At most one HASH, which is what scopes a search to one tenant here, and any number of INLINE_FILTERs. Every attribute you name has to appear in AttributeDefinitions too, which is the reverse of the rule for the vector attribute itself, so it is easy to get backwards.

The filters run inside the search rather than after it. That is the opposite of a FilterExpression on a Query, where you pay for every row read and then discard most of them. Narrowing a search costs you nothing extra.

One thing worth being blunt about: the HASH is not a security boundary. It decides where data sits and how throughput spreads across partitions, and that is all it does. Fine-grained access control does not apply to SearchVectors, so anyone permitted to search this index can read any tenant's incidents by changing one string in the request. Tenants that must genuinely be isolated need separate tables, or separate indexes with their own IAM grants.

And one failure you will not see coming: an item missing the attribute the SearchSchema uses as its HASH is written to the table successfully and left out of the index. No error, no warning, and it never turns up in a search. An item missing an INLINE_FILTER attribute is fine and stays indexed. The two behave differently and neither tells you.

Nominate your filterable attributes at index creation and use = on them; anything else is refused outright, and the HASH partitions data rather than securing it.

IncidentTriage

These rows are real and already here. Running an operation against them downloads a DynamoDB-compatible engine, about 850 KB, and executes it in this tab.

Try an example

One tenant, open incidents, checkout service. tenantId is the SearchSchema's HASH; status and service are INLINE_FILTERs. All three were nominated when the index was created, so all three are allowed.

pk(pk)
sk(sk)
tenantId
status
service
severity
assignee
summary
embedding
TENANT#t-northwind
INCIDENT#inc-1001S
t-northwindS
openS
checkoutS
1N
raeS
Checkout returns 500 on card authorisationS
[0.0819, 0.0687, -0.0332, … 384]L
TENANT#t-northwind
INCIDENT#inc-1002S
t-northwindS
openS
checkoutS
2N
samS
Checkout latency above two seconds at peakS
[0.0715, -0.0286, -0.0274, … 384]L
TENANT#t-northwind
INCIDENT#inc-1003S
t-northwindS
openS
paymentsS
2N
raeS
Payment webhooks arriving twice for one orderS
[-0.0557, 0.0585, 0.0442, … 384]L
TENANT#t-northwind
INCIDENT#inc-1004S
t-northwindS
closedS
searchS
3N
kitS
Search results empty for accented queriesS
[0.061, -0.0397, -0.0007, … 384]L
TENANT#t-northwind
INCIDENT#inc-1005S
t-northwindS
closedS
checkoutS
2N
samS
Checkout basket clears when the session refreshesS
[0.0898, -0.0168, 0.0105, … 384]L
TENANT#t-northwind
INCIDENT#inc-1006S
t-northwindS
openS
exportsS
3N
kitS
Nightly export job times out on large accountsS
[0.0286, 0.0255, -0.0357, … 384]L
TENANT#t-lumen
INCIDENT#inc-2001S
t-lumenS
openS
checkoutS
2N
olaS
Checkout rejects valid postcodes in IrelandS
[0.0142, -0.0114, -0.0403, … 384]L
TENANT#t-lumen
INCIDENT#inc-2002S
t-lumenS
openS
authS
1N
olaS
Login page blank on first load in SafariS
[0.0052, -0.0251, 0.0094, … 384]L
TENANT#t-lumen
INCIDENT#inc-2003S
t-lumenS
closedS
authS
3N
vanS
Password reset emails landing in spamS
[-0.0452, -0.0617, -0.0015, … 384]L
TENANT#t-lumen
INCIDENT#inc-2004S
t-lumenS
openS
reportingS
3N
vanS
Dashboard charts render a day behindS
[0.0073, 0.0327, 0.0527, … 384]L
TENANT#t-atlas
INCIDENT#inc-3001S
t-atlasS
openS
checkoutS
1N
wenS
Checkout card form fails on mobile SafariS
[-0.0346, 0.0207, 0.0152, … 384]L
TENANT#t-atlas
INCIDENT#inc-3002S
t-atlasS
openS
inventoryS
2N
wenS
Stock counts drift after a failed orderS
[-0.0279, -0.068, 0.0829, … 384]L

Run an operation to see the raw engine response.

table IncidentTriagekeys pk / skitems 12