basic concept to read: https://www.dynamodbguide.com/
Also, as MongoDB is much more flexible about indices than DDB, it's less dangerous to try out STD in MongoDB.
-
collection: dashboard
-
2 types: [dashboard, widget]
-
pk
: partition key for records, how records should be grouped, allocated -
sk
: sorting key for a record inside a partition
pk+sk
: primary key for pinpointing one record
type | pk | sk | explanation |
---|---|---|---|
dashboard | d#dashboard_id | d#dashboard_id | (prefixed) mongo id or any lexicographically sortable id, pk === sk |
widget | d#dashboard_id | w#widget_id | pk contains the dashboard's mongo id, sk contains the widget's own mongo id |
access pattern | query | pagination | explanation |
---|---|---|---|
get me a dashboard | {pk: d#dashboard_id, sk: d#dashboard_id} or {sk: d#dashboard_id} | NA | |
get me a dashboard and its widgets | {pk: d#dashboard_id}, {limit, sortBy: sk ascending} | {pk: d#dashboard_id, sk: {$gt: last w#widget_id}} | |
give me all dashboards I can see | {pk: /^d#/, sk: /^d#/, acl filters}, { limit } | {pk: /^d#/, acl filters, $and: [{sk: /^d#/}, {sk: {$gt: last d#dashboard_id}}]} | |
give me all widgets I can see | {pk: /^d#/}, sk: /^w#/, acl filters}, { limit } | {pk: /^d#/, acl filters, $and: [{sk: /^w#/}, {sk: {$gt: last w#widget_id}}]} | all widgets belong to at least one dashboard or they don't exist |
give me all widgets I can see | {sk: /^w#/, acl filters} | {$and: [{sk: /^w#/}, {sk: {$gt: last w#widget_id, acl filters}}]} | if a widget is not necessarily bound to any dashboard, flexibility of MongoDB allows us to use sk directly, not necessarily always use pk+sk pattern, might even be the preferred way after all |
update or delete one dashboard | {pk: d#dashboard_id, sk: d#dashboard_id} or {sk: d#dashboard_id} | ||
update or delete one widget | {pk: d#dashboard_id, sk: w#dashboard_id} or {sk: w#dashboard_id} |
type | pk | sk | explanation |
---|---|---|---|
dashboard | d#dashboard_id1 | w#dashboard_id1 | |
dashboard | d#dashboard_id2 | w#dashboard_id2 | |
widget | [d#dashboard_id1, d#dashboard_id2] | w#widget_id | power of MongoDB arrays |
{pk: d#dashboard_id1}
will yield dashboard1
and widget
records
{pk: d#dashboard_id2}
will yield dashboard1
and widget
records
if we are sure no widget will be reused in other dashboards, we can ignore this part.
note the usage of type prefixed at pk and sk, with it we can do some clever sorting. for example if one widget was created before a dashboard record and we want to reuse it, if we only use default mongo id in pk and sk, we could have mixed order in response:
type | pk | sk |
---|---|---|
widget | 123456 | 000000 |
dashboard | 123456 | 111111 |
widget | 123456 | 222222 |
{pk: 123456}, {sortBy: sk ascending}
will give us first the widget then the dashboard and again
another widget, it's hard to do pagination.
when we prefix the ids
type | pk | sk |
---|---|---|
widget | d#123456 | w#000000 |
dashboard | d#123456 | d#111111 |
widget | d#123456 | w#222222 |
{pk: d#123456}, {sortBy: sk ascending}
will always first give us one dashboard record and we can
be sure in the later pages we will only get widget.