Momento Cache 4つのコレクションデータ その4 Sorted Sets
今までの記事で3つのコレクションデータ型を触ってきました。
[Dictionary]
[List]
[Sets]
この記事ではいよいよ最後4つ目のSorted Setsを触っていきます。
Sorted Sets とは
ユニークな要素の文字列による、順序のないコレクション
として定義されていますが、Sorted Setsはその名前の通りユニークな要素の順序付きコレクション
です。
追加として、各要素の値はペアとなる符号付き64ビット浮動小数点数を持ち、スコアと呼ばれます。少しイメージしずらいかもしれませんが、やってみればすぐわかります。
さっそくやってみる
ややこしいので一度言葉を整理します。
キー:Sorted Setsのアイテムを保持します。キーは一意の識別子です。
アイテム:キーと紐づくSorted Setsの本体です。
要素:Sorted Setsが保持するデータで、複数の値
と、ペアとなるスコア
を持ちます。
元々がネスト構造化されたデータフォーマットなので、日本語にするのはややこしいですね。
まずは以下を実行します。アイテムの書き込みにはsortedSetPutElement
を使います。アイテムが存在していない場合は自動で作ってくれた後、要素を書き込みます。
// Declare the Momento SDK library
const {
Configurations,
CacheClient, CredentialProvider,
CacheSortedSetPutElement,
} = require('@gomomento/sdk');
// Declate the dotenv library
const dotenv = require('dotenv');
// Run the config function to bring in the .env file
dotenv.config();
// Creates the Momento cache client object
async function createCacheClient() {
return await CacheClient.create({
configuration: Configurations.Laptop.v1(),
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
defaultTtlSeconds: 600,
});
}
// A simple function that calls all functions in order. You probably want more error handling.
async function run() {
const cacheClient = await createCacheClient();
const result = await cacheClient.sortedSetPutElement('demo-cache', 'test-sorted-set', 'test-value', 5);
if (result instanceof CacheSortedSetPutElement.Success) {
console.log("Value 'test-value' with score '5' added successfully to sorted set 'test-sorted-set'");
} else if (result instanceof CacheSortedSetPutElement.Error) {
throw new Error(
`An error occurred while attempting to call cacheSortedSetPutElement on sorted set 'test-sorted-set' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
}
run();
const result = await cacheClient.sortedSetPutElement('demo-cache', 'test-sorted-set', 'test-value', 5);
Value 'test-value' with score '5' added successfully to sorted set 'test-sorted-set'
demo-cache
というキャッシュに、test-sorted-set
というキー持つアイテム作成し、test-value
という値が5
というスコアを持っています。ややこしいですがJSONにすると簡単です。
SortedSetPutElements
を使うことで複数要素を一度にアイテムに書き込むことが可能です。
// Declare the Momento SDK library
const {
Configurations,
CacheClient, CredentialProvider,
CacheSortedSetPutElement,
} = require('@gomomento/sdk');
// Declate the dotenv library
const dotenv = require('dotenv');
// Run the config function to bring in the .env file
dotenv.config();
// Creates the Momento cache client object
async function createCacheClient() {
return await CacheClient.create({
configuration: Configurations.Laptop.v1(),
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
defaultTtlSeconds: 600,
});
}
// A simple function that calls all functions in order. You probably want more error handling.
async function run() {
const cacheClient = await createCacheClient();
const result = await cacheClient.sortedSetPutElements(
'demo-cache',
'test-sorted-set',
new Map ([
['key1', 10],
['key2', 20],
])
);
if (result instanceof CacheSortedSetPutElements.Success) {
console.log("Elements added successfully to sorted set 'test-sorted-set'");
} else if (result instanceof CacheSortedSetPutElements.Error) {
throw new Error(
`An error occurred while attempting to call cacheSortedSetPutElements on sorted set 'test-sorted-set' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
}
run();
const result = await cacheClient.sortedSetPutElements(
'demo-cache',
'test-sorted-set',
new Map ([
['key1', 10],
['key2', 20],
])
);
Dictionary
と同じようにMap
が使えます。(MomentoのAPIドキュメントではTypescriptになっていたのでJavaScriptに直しています。)
先ほどの結果に対して値とスコアが追記され、アイテムが複数の要素を持っていることがわかります。
Get と Fetch
今までの3つのコレクションデータ型では要素の取得にはFetch
を使っていました。Sorted Sets
ではGet
とFetch
の2種類が明確に異なるき機能として定義されています。
(ちなみに通常のKey-Value型キャッシュデータはGetを使います)
簡単にまとめるとSorted Sets
におけるGet
とFetch
は以下の違いがあります。
Get
: 値を指定することでスコアを取り出します。
Fetch
:スコアの順位や範囲指定により、値とスコアのペアを取り出します。
Sets
とことなりSorted Sets
が順序を保証しているのはこの辺りがミソです。
では早速やってみます。まずはGet
から。SortedSetGetScore
を使います。
// Declare the Momento SDK library
const {
Configurations,
CacheClient, CredentialProvider,
CacheSortedSetPutElement,
CacheSortedSetPutElements,
CacheSortedSetGetScore,
} = require('@gomomento/sdk');
// Declate the dotenv library
const dotenv = require('dotenv');
// Run the config function to bring in the .env file
dotenv.config();
// Creates the Momento cache client object
async function createCacheClient() {
return await CacheClient.create({
configuration: Configurations.Laptop.v1(),
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
defaultTtlSeconds: 600,
});
}
// A simple function that calls all functions in order. You probably want more error handling.
async function run() {
const cacheClient = await createCacheClient();
await cacheClient.sortedSetPutElements(
'demo-cache',
'test-sorted-set',
new Map([
['key1', 10],
['key2', 20],
])
);
const result = await cacheClient.sortedSetGetScore('demo-cache', 'test-sorted-set', 'key1');
if (result instanceof CacheSortedSetGetScore.Hit) {
console.log(`Element with value 'key1' has score: ${result.score()}`);
} else if (result instanceof CacheSortedSetGetScore.Miss) {
console.log("Sorted Set 'test-sorted-set' was not found in cache 'test-cache'");
} else if (result instanceof CacheSortedSetGetScore.Error) {
throw new Error(
`An error occurred while attempting to call cacheSortedSetFetchGetScore on sorted set 'test-sorted-set' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
}
run();
const result = await cacheClient.sortedSetGetScore('demo-cache', 'test-sorted-set', 'key1');
Element with value 'key1' has score: 10
値key1
はスコア10
を持っていることがわかります。SortedSetGetScores
でまとめて取り出すことも可能です。
次にSortedSetFetchByRank
を試してみます。
// Declare the Momento SDK library
const {
Configurations,
CacheClient, CredentialProvider,
CacheSortedSetPutElement,
CacheSortedSetPutElements,
CacheSortedSetGetScore,
CacheSortedSetFetch,
} = require('@gomomento/sdk');
// Declate the dotenv library
const dotenv = require('dotenv');
// Run the config function to bring in the .env file
dotenv.config();
// Creates the Momento cache client object
async function createCacheClient() {
return await CacheClient.create({
configuration: Configurations.Laptop.v1(),
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
defaultTtlSeconds: 600,
});
}
// A simple function that calls all functions in order. You probably want more error handling.
async function run() {
const cacheClient = await createCacheClient();
await cacheClient.sortedSetPutElements(
'demo-cache',
'test-sorted-set',
new Map ([
['key1', 10],
['key2', 20],
])
);
const result = await cacheClient.sortedSetFetchByRank('demo-cache', 'test-sorted-set');
if (result instanceof CacheSortedSetFetch.Hit) {
console.log("Values from sorted set 'test-sorted-set' fetched by rank successfully- ");
result.valueArray().forEach(res => {
console.log(`${res.value} : ${res.score}`);
});
} else if (result instanceof CacheSortedSetFetch.Miss) {
console.log("Sorted Set 'test-sorted-set' was not found in cache 'test-cache'");
} else if (result instanceof CacheSortedSetFetch.Error) {
throw new Error(
`An error occurred while attempting to call cacheSortedSetFetchByRank on sorted set 'test-sorted-set' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
}
run();
const result = await cacheClient.sortedSetFetchByRank('demo-cache', 'test-sorted-set');
スコアの順位順に値が表示されます。
Values from sorted set 'test-sorted-set' fetched by rank successfully-
key1 : 10
key2 : 20
SortedSetGetRank
を使うことで、指定した値の順位が何以下?を知ることもできます。
次にSortedSetFetchByScore
を試してみます。
// Declare the Momento SDK library
const {
Configurations,
CacheClient, CredentialProvider,
CacheSortedSetPutElement,
CacheSortedSetPutElements,
CacheSortedSetGetScore,
CacheSortedSetFetch,
} = require('@gomomento/sdk');
// Declate the dotenv library
const dotenv = require('dotenv');
// Run the config function to bring in the .env file
dotenv.config();
// Creates the Momento cache client object
async function createCacheClient() {
return await CacheClient.create({
configuration: Configurations.Laptop.v1(),
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
defaultTtlSeconds: 600,
});
}
// A simple function that calls all functions in order. You probably want more error handling.
async function run() {
const cacheClient = await createCacheClient();
await cacheClient.sortedSetPutElements(
'demo-cache',
'test-sorted-set',
new Map ([
['key1', 100],
['key2', 25],
])
);
const result = await cacheClient.sortedSetFetchByScore('demo-cache', 'test-sorted-set');
if (result instanceof CacheSortedSetFetch.Hit) {
console.log("Values from sorted set 'test-sorted-set' fetched by score successfully- ");
result.valueArray().forEach(res => {
console.log(`${res.value} : ${res.score}`);
});
} else if (result instanceof CacheSortedSetFetch.Miss) {
console.log("Sorted Set 'test-sorted-set' was not found in cache 'demo-cache'");
} else if (result instanceof CacheSortedSetFetch.Error) {
throw new Error(
`An error occurred while attempting to call cacheSortedSetFetchByScore on sorted set 'test-sorted-set' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
}
run();
Values from sorted set 'test-sorted-set' fetched by score successfully-
key2 : 25
key1 : 100
またオプションパラメーターでminScore
,maxScore
が準備されており、指定した範囲のスコアを持つ値を出力することが可能です。order
により昇順、降順の指定も可能になっています。
sortedSetPutElement
で値とペアとなるスコアを増やしたり減らしたりすることが可能です。
// Declare the Momento SDK library
const {
Configurations,
CacheClient, CredentialProvider,
CacheSortedSetPutElement,
CacheSortedSetPutElements,
CacheSortedSetGetScore,
CacheSortedSetFetch,
sortedSetPutElement,
CacheSortedSetIncrementScore,
} = require('@gomomento/sdk');
// Declate the dotenv library
const dotenv = require('dotenv');
// Run the config function to bring in the .env file
dotenv.config();
// Creates the Momento cache client object
async function createCacheClient() {
return await CacheClient.create({
configuration: Configurations.Laptop.v1(),
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
defaultTtlSeconds: 600,
});
}
// A simple function that calls all functions in order. You probably want more error handling.
async function run() {
const cacheClient = await createCacheClient();
await cacheClient.sortedSetPutElement('demo-cache', 'test-sorted-set', 'test-value', 10);
const result = await cacheClient.sortedSetIncrementScore('demo-cache', 'test-sorted-set', 'test-value', 1);
if (result instanceof CacheSortedSetIncrementScore.Success) {
console.log(`Score for value 'test-value' incremented successfully. New score - ${result.score()}`);
} else if (result instanceof CacheSortedSetIncrementScore.Error) {
throw new Error(
`An error occurred while attempting to call cacheSortedSetIncrementScore on sorted set 'test-sorted-set' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
}
run();
await cacheClient.sortedSetPutElement('demo-cache', 'test-sorted-set', 'test-value', 10);
const result = await cacheClient.sortedSetIncrementScore('demo-cache', 'test-sorted-set', 'test-value', 1);
'test-value'という値とペアとなる10
というスコアを持つ要素を作成しています。
その後sortedSetIncrementScore
で1を足しています。
Score for value 'test-value' incremented successfully. New score - 11
マイナスの値を指定することで数字を減らすことも可能です。
これは処理の高速化とコードの簡素化を実現します。通常キャッシュ内の値を増減させる場合以下のステップを踏みます。
1.値の取り出し
2.値に対する数字の修正
3.値の上書き
これを1つの関数でまとめて行うことが可能です。
削除はいつも通りキーを指定して通常のアイテムとして削除が可能です。
Discussion