数据存储中的实体似乎使用其祖先密钥作为其位置的一部分,这可以依赖吗?

It appears that entities in datastore use their ancestor key as part of their location, can this be relied on?

这是我在 Datastore 模拟器中的测试设置 运行 gcloud beta emulators datastore start --no-store-on-disk

使用 NodeJS 客户端,设置如下。请注意,出于示例的目的,我使用简单的 Kind + Name 组合作为祖先。我知道最佳实践文档不鼓励单调生成自定义名称。

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"
    }
]

所以我想确认这确实是正确的行为,而不仅仅是模拟器的产物。如果这就是事情应该如何工作的话,那么只要祖先的 Kind + Name 提供足够的信息,就可以考虑使用 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']

或者这仍然只是个坏主意?

这是实体由键的整个路径键控的正确行为,即它包括所有祖先键。

如果你有一个唯一的(每个进程)前缀,那么你就不需要担心单调递增的键,因为写入实际上是 spaced 在键 space 中由你的前缀.因此,这应该是一个可扩展的解决方案。