如何解决看来数据存储区中的实体使用其祖先键作为其位置的一部分,这是否可以依赖?
这是我的测试设置,它在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','3','4',];
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,3,4,"text": "Lorem Ipsum"
}
]
所以我想确认这确实是正确的行为,而不仅仅是模拟器的人工产物。如果这是应该工作的方式,那么接下来就可以考虑使用unix时间戳做一个时间序列,只要祖先的种类+名称提供了足够的保护以防止碰撞。在这种情况下,只要请求写入的进程未以会导致时间戳冲突的规模进行写入,那么UUID可能就足够了。在此示例中,我们假设每个UUID不再需要1个进程。
['A','95a69d2f-adac-4da7-b1ab-134ca0e7a840','1000000005000']
['A','1000000006000']
['A','1000000007000']
还是这只是个坏主意?
解决方法
这是实体通过键的整个路径键控的正确行为,即它包括所有祖先键。
如果您具有唯一的(每个进程)前缀,那么您不必担心单调递增的密钥,因为写入实际上是由前缀在密钥空间中隔开的。因此,这应该是一个可扩展的解决方案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。