Momento Cache 4つのコレクションデータ その1 Dictionary
Momento Cacheには標準系のKey-Valueに加えて4つのコレクションデータ型があります。
標準系は以下の記事でやった通りです。
const setResponse = await client.set(cacheName, key, data);
const readResponse = await client.get(cacheName, key);
のように単純にKey Valueを扱います。
このKeyに対してネストされたデータを取り扱うことを可能とし、アプリケーション側での実装負担を少なくするものがコレクションデータ型です。
・Dictionary
・Lists
・Sets
・Sorted Sets
です。これから4回シリーズでそれを見ていきたいと思います。
Dictionary
以下のようにNestされたデータを単一のKeyに持たせることが出来ます。
test-dictionary
というキーに対して
{
"test-field": "test-value",
"key1": "value1",
"key2": "value2"
}
がセットされています。
早速やってみる
test.js
の実行まで終わらせておきましょう。
test.js
を以下に改造します。
const {
Configurations,
CacheClient, CredentialProvider,
CacheDictionarySetField,
} = require('@gomomento/sdk');
const dotenv = require('dotenv');
dotenv.config();
async function createCacheClient() {
return await CacheClient.create({
configuration: Configurations.Laptop.v1(),
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
defaultTtlSeconds: 600,
});
}
async function run() {
const cacheClient = await createCacheClient();
const result = await cacheClient.dictionarySetField('demo-cache', 'test-dictionary', 'test-field', 'test-value');
if (result instanceof CacheDictionarySetField.Success) {
console.log("Field set successfully into cache 'test-cache'");
} else if (result instanceof CacheDictionarySetField.Error) {
throw new Error(
`An error occurred while attempting to call cacheDictionarySetField on dictionary 'test-dictionary' in cache 'demo-cache': ${result.errorCode()}: ${result.toString()}`
);
}
}
run();
実行が成功すると
Field set successfully into cache 'demo-cache'
と表示されます。
const result = await cacheClient.dictionarySetField('demo-cache', 'test-dictionary', 'test-field', 'test-value');
が実体です。demo-cache
という名前のキャッシュに、test-dictionary
というキーを用いて、
'test-field', 'test-value'
を書き込んでいます。
少しややこしいのですが、特定のキーに紐付いているアイテムが存在し、そのアイテムがDictionaryです。そしてDictionaryアイテムの中に格納さるフィールドは複数存在することが可能で、フィールド自体がネストされたKey-Valueを構成できます。
またここは注意点ですがDictionaryは順序付けされていない要素の集まりです。つまり順番はばらばらに出力されます。これは同じDictionaryアイテムの呼び出しにおいても中のフィールドは順番が時と場合によって異なって出力されます。その分ネストされたアイテムでも早く動作します。
以下のような指定も可能です。
const {
Configurations,
CacheClient, CredentialProvider,
CacheDictionarySetField,
CacheDictionarySetFields,
} = require('@gomomento/sdk');
<snip>
async function run() {
const cacheClient = await createCacheClient();
const result = await cacheClient.dictionarySetFields(
'demo-cache',
'test-dictionary',
new Map([
['key1', 'value1'],
['key2', 'value2'],
])
);
if (result instanceof CacheDictionarySetFields.Success) {
console.log("Fields set successfully into cache 'demo-cache'");
} else if (result instanceof CacheDictionarySetFields.Error) {
throw new Error(
`An error occurred while attempting to call cacheDictionarySetFields on dictionary 'test-dictionary' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
}
<snip>
この例ではCacheDictionarySetField
の代わりにCacheDictionarySetFields
を用いています。Value
にはMap
を用いることでさらにネストさせたデータを書き込んでいます。
Valueから特定のネストされたFiledだけを削除することも可能です。
const {
Configurations,
CacheClient, CredentialProvider,
CacheDictionarySetField,
CacheDictionarySetFields,
CacheDictionaryRemoveField,
} = require('@gomomento/sdk');
<snip>
const result = await cacheClient.dictionaryRemoveField('demo-cache', 'test-dictionary', 'test-field');
if (result instanceof CacheDictionaryRemoveField.Success) {
console.log("Field removed successfully from dictionary 'test-dictionary'");
} else if (result instanceof CacheDictionaryRemoveField.Error) {
throw new Error(
`An error occurred while attempting to call cacheDictionaryRemoveField on dictionary 'test-dictionary' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
<snip>
以下のようにFieldが一つ消えています。
キーに紐付く値を全て取得するのは以下で行えます。
const {
Configurations,
CacheClient, CredentialProvider,
CacheDictionarySetField,
CacheDictionarySetFields,
CacheDictionaryRemoveField,
CacheDictionaryFetch,
} = require('@gomomento/sdk');
<snip>
const result = await cacheClient.dictionaryFetch('demo-cache', 'test-dictionary');
if (result instanceof CacheDictionaryFetch.Hit) {
console.log('Dictionary fetched successfully- ');
result.valueMapStringString().forEach((value, key) => {
console.log(`${key} : ${value}`);
});
} else if (result instanceof CacheDictionaryFetch.Miss) {
console.log("Dictionary 'test-dictionary' was not found in cache 'demo-cache'");
} else if (result instanceof CacheDictionaryFetch.Error) {
throw new Error(
`An error occurred while attempting to call cacheDictionaryFetch on dictionary 'test-dictionary' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
<snip>
Dictionary fetched successfully-
key1 : value1
key2 : value2
現在Dictionaryアイテムをまとめて削除するAPIが無いようです。と、思いきやtest-dictionary
がただのキャッシュキーとして指定可能ですので以下で削除できました。
const result = await cacheClient.delete('demo-cache', 'test-dictionary');
詳しいAPI諸元はこちらです。Lists
型を見ていきます!
(2023/12/06追記)
特定の値を持つFieldだけを抜き出す方法です。例えば以下の値がある場合
{
"test-field": "test-value",
"key2": "value2",
"key1": "value1"
}
value1
だけを取り出すには
const result2 = await cacheClient.dictionaryGetField('demo-cache', 'test-dictionary','key1');
を使います。
const {
Configurations,
CacheClient, CredentialProvider,
CacheDictionarySetField,
CacheDictionarySetFields,
} = require('@gomomento/sdk');
const dotenv = require('dotenv');
dotenv.config();
async function createCacheClient() {
return await CacheClient.create({
configuration: Configurations.Laptop.v1(),
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
defaultTtlSeconds: 600,
});
}
async function run() {
const cacheClient = await createCacheClient();
const result = await cacheClient.dictionarySetFields(
'demo-cache',
'test-dictionary',
new Map([
['key1', 'value1'],
['key2', 'value2'],
])
);
if (result instanceof CacheDictionarySetFields.Success) {
console.log("Fields set successfully into cache 'demo-cache'");
} else if (result instanceof CacheDictionarySetFields.Error) {
throw new Error(
`An error occurred while attempting to call cacheDictionarySetFields on dictionary 'test-dictionary' in cache 'test-cache': ${result.errorCode()}: ${result.toString()}`
);
}
const result2 = await cacheClient.dictionaryGetField('demo-cache', 'test-dictionary', 'key1');
console.log("result2 is " + result2);
}
run()
Discussion