祖先查询直接后代 - Google 数据存储

Posted

技术标签:

【中文标题】祖先查询直接后代 - Google 数据存储【英文标题】:Ancestor Query Direct Descendants - Google Datastore 【发布时间】:2015-10-07 19:33:14 【问题描述】:

我正在使用 Go 和 Google Datastore 在 Google App Engine 中构建目录应用程序。我正在使用数据存储区的Ancestor 功能来管理不同的产品类别。以下是一些数据的示例:

Musical Instruments -> Guitars -> Gibson -> Les Paul

Musical Instruments -> Guitars -> Fender -> Stratocaster

Musical Instruments -> Bass Guitars -> Music Man -> Stingray

Musical Instruments 是根实体。当我单击它时,我希望看到GuitarsBass Guitars,但相反,我看到的所有内容都是Musical Instruments 的后代,一直到最后一个实体。这不是我要找的。目前我只对乐器的直系后代感兴趣。

like this one 的一些帖子建议在数据存储区中创建一个字段来跟踪直接父母。但是,如果我要手动跟踪父实体,为什么要使用 Ancestor 功能呢?它会比过滤匹配直接父字段的查询更快吗?

获取类别的方法如下:

func (cat *Category) GetCategories(r *http.Request, pk string) ([]CategoryReturn, error) 
//get context
c := appengine.NewContext(r)

var q *datastore.Query
var err error

//get parent key
k, err := datastore.DecodeKey(pk)

if err != nil 
    //handle error
    return []CategoryReturn, err


q = datastore.NewQuery("Category").Ancestor(k)

//populate category slices
var categories []CategoryReturn
keys, err := q.GetAll(c, &categories)

if err != nil 
    //handle error
    return []CategoryReturn, err


//create return object
results := make([]CategoryReturn, 0, 20)

for i, r := range categories 
    k := keys[i]
    y := CategoryReturn 
        Name: r.Name,
        Id: k.IntID(),
        Key: k.Encode(),
    

    results = append(results, y)


return results, nil


【问题讨论】:

你能发布你的代码来显示你的祖先查询吗?我的预感是您可能不想以这种方式使用祖先,因为它们会影响您对所有乐器的写入速率。您是否需要整个乐器实体组的强一致性? 增加了获取类别的方法。对于应用程序的这个特定部分,我不需要强一致性。 【参考方案1】:

您需要考虑应用程序中确实需要强一致性的任何部分,然后考虑哪些实体和实体组需要参与相应的查询和事务(您现在可以在一个跨组中拥有多达 25 个交易),但你以这种方式使用祖先给我敲响了警钟。

通过将实体组视为逻辑结构数据模型的一种方式,很容易被实体组所吸引(我有!),但这可能会导致问题,最终导致不必要的大写争用实体组。

相反,最好考虑应用程序中需要强一致性的点,并围绕这些点设计实体组。

在这种情况下,我可能只有一个parentCategory 属性(datastore.Key 类型)。然后,您可以像这样查询 Musical Instruments 的子类别:

k := datastore.NewKey(c, "Category", "Musical Instruments", 0, nil)
q := datastore.NewQuery("Category").Filter("parentCategory =", k)

(我对 Go 很陌生,所以上面可能是一个近似值)

假设在每个类别中您都有某种Product,并且您希望在树中的任何级别(例如,Telecaster 中的Telecaster GuitarsMusical Instruments 中的 Minimoog 那么您可能需要一个多值属性(在 Go 中我猜这可能是 @987654327 @slice) 表示类别树的分支。

【讨论】:

好的,现在说得通了。文档并没有真正建议不要以这种方式使用它,但很明显它不是为产品类别设计的。为 Minimoog +1。

以上是关于祖先查询直接后代 - Google 数据存储的主要内容,如果未能解决你的问题,请参考以下文章

查询自引用表中所有连接的祖先和后代

12.组件化开发2-非父子组件之间通信-祖先和后代之间的通信

jQuery---[jQuery筛选之::祖先,后代,同胞,过滤,判断]

ADT 树 - 是节点本身的祖先/后代吗?

如何找到具有某个标签的后代叶节点的最低祖先?

数据存储模拟器返回“事务内只允许祖先查询”。它不支持 Datastore 模式下的 Firestore 吗?