LoginSignup
3
2

More than 1 year has passed since last update.

DynamoDB timestamp を文字列と数値で Between 結果を一緒にする方法

Last updated at Posted at 2022-12-10

背景

DynamoDB のテーブルにて、複合ソートキーのテーブルがあった。
複数の属性を "#" で結合したソートキー、って聞いた。

当初は以下みたいな感じかと思った

  • 自動で属性を選択したら ソートキーが出来る
  • 選択した属性単位で上手く検索出来る

そしたら、以下だった・・

  • 単なる文字列
  • "#" 自身で Join/Split する
  • もしくは、属性を別途作成して保存しておき利用する。
      • timestamp#id <複合ソートキー
      • timestamp
      • id

ここで問題となるのが以下。で、この解消法を記録

属性 Between 理由
timestamp#id 文字列 lower <= x < upper その後に続く文字がある為、上限一致しない
timestamp 数値 lower <= x <= upper 数値であり、上限も一致する

結論

数値側の上限を除外すればいいので、FilterExpression ではじくのが一番マシかな、と

単純に SK として使う場合は文字列
Index で timestamp: number を利用する場合には、上限を弾く

FilterExpression
const paramsQuery = {
  TableName: "User",
  IndexName: "user-post-index",
  ExpressionAttributeNames: {
    "#PK": "uid",
    "#SK": "timestamp",
    "#SKupper": "timestamp#post_id",  // Index では、単なる属性
  },
  ExpressionAttributeValues: {
    ":PK": "userID_0001",
    ":sortkeyval1": 1670550736983,
    ":sortkeyval2": 1670550736993,
    ":SKupper": "1670550736993",  // sortkeyval2 の文字列化
  },
  KeyConditionExpression: "#PK =:PK AND (  #SK BETWEEN :sortkeyval1 AND :sortkeyval2 )",
  FilterExpression: "#SKupper < :SKupper",
};
const users = (await ddbDocClient.send(new import_lib_dynamodb2.QueryCommand(paramsQuery)));

複合ソートキーは単なる文字列検索&ソートなんですね

この場合、時刻 + ID にすると意味は無くて、日付 + ID なら、かなぁ。この設計でいいんだろうか?という疑問が・・

説明にあった以下のような階層化のほうが分かりやすいね

[country]#[region]#[state]#[county]#[city]#[neighborhood]

検証

色々と試してみた記録

ソート

色々入れてみたけど、結局日付とか関係なしに、文字の先頭からの文字コードソートって感じ
故に、文字列書式で Zero padding とかちゃんとしておけば大丈夫って話
image.png

クエリ

文字列として検索するって考えれば、まぁ、普通。
EndsWith や Contains なんかもあればいいのに、とは思うけど。

条件 結果
次と等しい
次以下 NG image.png
次よりも小さい OK image.png
次以上 OK image.png
次よりも大きい NG image.png
次の間 以上 + よりも小さい と考えるとOK image.png
次で始まる 普通に BeginsWith image.png

あとがき

RDB とは違うんだよ、RDB とはって声が聞こえてくる感じ
色々学んでいく事が多いですね。

まずは、Lib.*Command を整理しておくところからかな

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2