
在 Google Cloud Datastore 中,实体的键(Key)是其唯一标识符。键的组成部分包括种类(Kind)、名称或 ID,以及祖先路径(Ancestor Path)。祖先路径定义了实体在数据层级结构中的位置。因此,无法直接在不改变实体键的情况下修改实体的祖先,因为祖先是键的一部分。
如果尝试更改实体的祖先,实际上是在创建一个新的实体,而原始实体仍然存在。这可能会导致数据不一致或其他问题,特别是在现有代码中已经使用旧键引用的情况下。
如果你的应用场景允许,可以考虑避免使用实体组,并采用以下替代方案:
type Employee struct {
Company string `datastore:"company"`
Department string `datastore:"department"`
Name string `datastore:"name"`
}q := datastore.NewQuery("Employee").
Filter("company =", "MyCompany").
Filter("department =", "MyDepartment")
var employees []*Employee
keys, err := client.GetAll(ctx, q, &employees)
if err != nil {
// Handle error
}以下是一个完整的示例,展示了如何使用属性来模拟层级关系:
package main
import (
"context"
"fmt"
"log"
"os"
"cloud.google.com/go/datastore"
)
type Employee struct {
Company string `datastore:"company"`
Department string `datastore:"department"`
Name string `datastore:"name"`
}
func main() {
ctx := context.Background()
// Replace "your-project-id" with your actual Google Cloud project ID.
projectID := os.Getenv("GOOGLE_CLOUD_PROJECT")
if projectID == "" {
log.Fatalf("GOOGLE_CLOUD_PROJECT environment variable must be set.")
}
client, err := datastore.NewClient(ctx, projectID)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
// Create a new Employee entity.
employee := &Employee{
Company: "MyCompany",
Department: "MyDepartment",
Name: "John Doe",
}
// Create a key for the entity.
key := datastore.NameKey("Employee", "john.doe", nil)
// Save the entity to Datastore.
_, err = client.Put(ctx, key, employee)
if err != nil {
log.Fatalf("Failed to save employee: %v", err)
}
fmt.Println("Employee saved successfully.")
// Query for the employee.
q := datastore.NewQuery("Employee").
Filter("company =", "MyCompany").
Filter("department =", "MyDepartment").
Filter("name =", "John Doe")
var employees []*Employee
keys, err := client.GetAll(ctx, q, &employees)
if err != nil {
log.Fatalf("Failed to query employees: %v", err)
}
if len(employees) > 0 {
fmt.Printf("Found employee: %+v, key: %+v\n", employees[0], keys[0])
} else {
fmt.Println("Employee not found.")
}
}注意事项:
使用属性进行查询时,需要注意数据一致性。Datastore 查询通常是最终一致的,这意味着在属性更新后,可能需要几秒钟的时间才能反映在查询结果中。
如果需要强一致性,可以通过键直接查找实体。按键查找始终返回最新的版本。
// Get the employee by key.
var employee Employee
err = client.Get(ctx, key, &employee)
if err != nil {
log.Fatalf("Failed to get employee by key: %v", err)
}
fmt.Printf("Employee retrieved by key: %+v\n", employee)虽然无法直接修改 Datastore 实体的祖先而不改变其键,但通过在实体中添加属性来表示层级关系,可以有效避免实体组带来的限制,并提供更灵活的数据管理方式。在选择方案时,请根据你的应用场景和对数据一致性的要求进行权衡。如果需要强一致性,请使用键直接查找实体。
以上就是更新 Datastore 实体:如何在不改变实体键的情况下修改祖先的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号