データストア内のエンティティは、場所の一部として祖先キーを使用しているようですが、これは信頼できますか?

Aug 20 2020

これは、データストアエミュレータで実行されているテストセットアップです。 gcloud beta emulators datastore start --no-store-on-disk

NodeJSクライアントを使用した場合のセットアップは次のとおりです。この例では、祖先に単純な種類と名前の組み合わせを使用していることに注意してください。ベストプラクティスドキュメントでは、単調に生成されたカスタム名を推奨していません。

const namespace = 'test';
const datastore = new Datastore();
const entities: any[] = [];
const paths = [
    ['A', '1', 'Z', '1'],
    ['A', '2', 'Z', '1'],
    ['A', '3', 'Z', '1'],
    ['A', '4', 'Z', '1'],
];

for (const path of paths) {
    const key = datastore.key({ path, namespace });
    const data = {
      text: 'Lorem Ipsum',
      path: key.path.toString(),
    };

    entities.push({ key, data });
}

const transaction = datastore.transaction();
await transaction.run();

transaction.upsert(entities);
await transaction.commit();

// wait a second for things to persist.
await new Promise((resolve) => {
    setTimeout(() => resolve(), 1000);
});

// Note that `hasAncestor` is **NOT** provided for this query.
const query = datastore.createQuery(namespace, 'Z');

const results = await datastore.runQuery(query);
expect(results[0]).toHaveLength(1); // fails, got 4 records back

Z祖先パスがエンティティのルックアップ場所に関係がない場合、すべての種類のエンティティをクエリすると、結果は1つだけになると思います。私のテストではそうではありませんが、4つの結果が返されます。クエリから返された各エンティティ間のパスが正しいことに注意してください。

[
    {
        "path": "A,1,Z,1",
        "text": "Lorem Ipsum"
    },
    {
        "path": "A,2,Z,1",
        "text": "Lorem Ipsum"
    },
    {
        "path": "A,3,Z,1",
        "text": "Lorem Ipsum"
    },
    {
        "path": "A,4,Z,1",
        "text": "Lorem Ipsum"
    }
]

したがって、これが実際に正しい動作であり、エミュレータのアーティファクトだけではないことを確認したかったのです。これが機能するはずの方法である場合、祖先の種類+名前が衝突に対して十分な保護を提供する限り、UNIXタイムスタンプを使用して時系列を実行することを検討しても問題ないでしょう。この場合、書き込みを要求するプロセスがタイムスタンプの衝突を引き起こすような規模で書き込みを行っていない限り、UUIDで十分である可能性があります。この例では、UUIDごとに1つのプロセスであると仮定します。

['A', '95a69d2f-adac-4da7-b1ab-134ca0e7a840', 'Z', '1000000005000']
['A', '95a69d2f-adac-4da7-b1ab-134ca0e7a840', 'Z', '1000000006000']
['A', '95a69d2f-adac-4da7-b1ab-134ca0e7a840', 'Z', '1000000007000']

それとも、これはまだ悪い考えですか?

回答

JimMorrison Aug 20 2020 at 23:14

これは、エンティティがキーのパス全体によってキー設定される正しい動作です。つまり、すべての祖先キーが含まれます。

一意の(プロセスごとの)プレフィックスがある場合、書き込みは実際にはプレフィックスによってキースペース内で間隔が空けられているため、単調に増加するキーについて心配する必要はありません。したがって、これはスケーラブルなソリューションである必要があります。