I'm having problems designing my DynamoDB table to support a fairly simple access pattern. I hope you can help me a little bit :)
I have 4 different products types (A, B, C and D) that have a price and a location (country#state#city).
The access patterns are:
- Filter by product type
- Filter by product type and location
- Filter by product type, location and price
- Filter by product type, location and price and sort by price
The problem is that a product located in USA#NY#NY must be also available in USA#NY and USA. Also, the user needs to be able to filter by price and sort by expensive/cheap first.
Example:
Data:
Product: ID_1 | Type A | Location USA#NY#NY | Price 100$ Product: ID_2 | Type A | Location USA#NY#NY | Price 200$
Use case:
- A user U1 search for products type A with price < 500$ in USA#NY#NY expensive first
- A user U2 search for products type A with price < 250$ in USA#NY cheap first
Expected result:
- U1 should get ID_2, ID_1
- U2 should get ID_1, ID_2
Both products should be displayed to both users in the right order even though they search in different areas.
To be able to filter by location and price and sort by price I came up with this solution, however, a lot of data gets duplicated and I am sure there must be a much better solution:
PK | SK & GSI PK | GSI SK | Other product details (duplicated data) --------------------------------------------------------------------------- ID | TYPE | PRICE | Image, name, etc ID | TYPE#USA | PRICE | Image, name, etc ID | TYPE#USA#NY | PRICE | Image, name, etc ID | TYPE#USA#NY#NY | PRICE | Image, name, etc
This solves every access pattern:
Filter by product type
GSI PK = TYPE
Filter by product type and location
GSI PK = begins_with(TYPE#USA#NY#...)
Filter by product type, location and price
GSI PK = TYPE#USA & GSI SK > 150
GSI PK = TYPE#USA#NY & GSI SK > 150
Filter by product type, location and price and sort by price
GSI PK = TYPE#USA & GSI SK > 150 ScanIndexForward true/false
GSI PK = TYPE#USA#NY & GSI SK > 150 ScanIndexForward true/false
Reads are efficient but a lot of data gets duplicated (price and product details) and updating an item requires multiple writes.
Is it possible to achieve this without duplicating all the product details?