douao1854 2015-10-07 19:33
浏览 22
已采纳

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

I'm building a catalog application in Google App Engine, using Go, and Google Datastore. I'm using the Ancestor features of the datatore to manage different product categories. Here's an example of some data:

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

Musical Instruments -> Guitars -> Fender -> Stratocaster

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

Musical Instruments is the root entity. When I click it, I expect to see Guitars and Bass Guitars, but instead I see everything that is a descendant of Musical Instruments all the way to the last entity. Which is not what I'm looking for. I'm only interested in the direct descendants of Musical instruments at this point.

Some posts, like this one, suggest creating a field in the datastore to track direct parents. But, if I'm going to track parent entities manually, why use the Ancestor features at all? Would it be faster than filtering queries who match a direct parent field?

Here's the method for getting categories:

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条回答 默认 最新

  • douhuzhi0907 2015-10-08 08:42
    关注

    You will need to think about any parts of your application that do need strong consistency and then consider what entities & entity groups will need to participate in the corresponding queries and transactions (you can now have up to 25 in a cross-group transaction), but your use of ancestors in this way rings alarm bells for me.

    It's easy to get caught out (I have!) with entity groups by thinking of them as a way to logically structure your data model, but this can cause problems down the line where you end up with write contention on an unnecessarily large entity group.

    Instead, it's best to think about the points in your application where you need strong consistency and design your entity groups around that.

    In this scenario I would probably just have a parentCategory property (of type datastore.Key). You can then query for subcategories of Musical Instruments like this:

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

    (I'm quite new to Go so the above might be an approximation)

    Assuming within each category you have some kind of Product and you want to query for all Products within a given Category at any level in the tree (e.g., Telecaster in Guitars, or Minimoog in Musical Instruments then you will probably need a multi-value property (in Go I guess this would probably be a []datastore.Key slice) representing the branch of the Category tree.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题