Appengine > Go > 映射数据存储结果

huangapple go评论113阅读模式
英文:

Appengine > Go > Mapping datastore results

问题

我正在尝试映射通过query.GetAll()检索到的结果。

我需要映射结果,因为模板将需要与每个实体关联的数据存储'Key'。

目前我正在做以下操作:

  1. // 查询
  2. q := datastore.NewQuery("Article").Limit(10)
  3. // 定义用于检索实体的数组
  4. var a[] Article;
  5. // 检索实体
  6. key, _ := q.GetAll(c, &a)
  7. // 创建一个空映射
  8. article := map[string] Article{}
  9. // 构建映射
  10. for k := range a {
  11. article[key[k].Encode()] = a[k];
  12. }
  13. template.Execute(w, map[string]interface{} { "Articles" : article})

是否有一种更高效的方法直接使用query.GetAll()构建映射,因为创建一个数组、一个映射并循环遍历数组来构建映射似乎不明智?

或者有一种更高效的方法来获取与每个实体关联的数据存储Key(编码)?

英文:

I'm trying to map the results retreived by query.GetAll()

I need to map the results since the Template will need the datastore 'Key' associated with each entity.

At the moment I'm doing the following:

  1. // Query
  2. q := datastore.NewQuery("Article").Limit(10)
  3. // Define array where the entities will be retreived
  4. var a[] Article;
  5. // Retreive entities
  6. key, _ := q.GetAll(c, &a)
  7. // Create an empty map
  8. article := map[string] Article{}
  9. // Build the map
  10. for k := range a {
  11. article[key[k].Encode()] = a[k];
  12. }
  13. template.Execute(w, map[string]interface{} { "Articles" : article})

Is there a more efficient way to build the map directly using query.GetAll(), since creating an array, a map and loop over the array to build the map doesn't seem wise?

Or a more efficient way to get the datastore Key (Encoded) associated with each entity?

答案1

得分: 1

也许最好的方法是将切片压缩成一个单一的切片。按照这个思路,

  1. package main
  2. import (
  3. "os"
  4. "text/template"
  5. )
  6. type pair struct {
  7. Key string
  8. Article string
  9. }
  10. var tmpt = `Here's the list:{{range $p := .}}
  11. {{$p.Key}}: {{$p.Article}}{{end}}
  12. `
  13. func main() {
  14. list := template.Must(template.New("list").Parse(tmpt))
  15. // 查询
  16. key := []string{"banana", "donkey", "curious"}
  17. a := []string{"长水果", "谁需要一个?", "人性"}
  18. // 压缩
  19. pairs := make([]pair, len(key))
  20. for i, k := range key {
  21. pairs[i].Key = k
  22. pairs[i].Article = a[i]
  23. }
  24. // 在压缩的列表上执行
  25. if err := list.Execute(os.Stdout, pairs); err != nil {
  26. os.Stdout.WriteString(err.Error())
  27. }
  28. }

输出:

  1. Here's the list:
  2. banana: 长水果
  3. donkey: 谁需要一个?
  4. curious: 人性
英文:

Maybe best is to zip the slices into a single slice. Along these lines,

  1. package main
  2. import (
  3. "os"
  4. "text/template"
  5. )
  6. type pair struct {
  7. Key string
  8. Article string
  9. }
  10. var tmpt = `Here's the list:{{range $p := .}}
  11. {{$p.Key}}: {{$p.Article}}{{end}}
  12. `
  13. func main() {
  14. list := template.Must(template.New("list").Parse(tmpt))
  15. // query
  16. key := []string{"banana", "donkey", "curious"}
  17. a := []string{"long fruit", "who needs one?", "human nature"}
  18. // zip
  19. pairs := make([]pair, len(key))
  20. for i, k := range key {
  21. pairs[i].Key = k
  22. pairs[i].Article = a[i]
  23. }
  24. // execute on zipped list
  25. if err := list.Execute(os.Stdout, pairs); err != nil {
  26. os.Stdout.WriteString(err.Error())
  27. }
  28. }

Output:
<pre>
Here's the list:
banana: long fruit
donkey: who needs one?
curious: human nature
</pre>

答案2

得分: 0

我认为你不需要使用map。如果我理解正确,在GetAll之后,你有两个并行的切片,key和a。(我不了解GAE,但是_让我感到疑惑。这是你应该检查的东西吗?)模板可以处理并行数组。在文档中可以看到range操作可以返回两个结果,一个是值,一个是索引。你应该可以遍历一个切片,并使用索引从另一个切片中获取相应的值。这将是一个更复杂的模板,但应该可以避免使用map。

编辑:抱歉,我以为我知道如何做到这一点,但是当我尝试编写一个示例代码时失败了。我会把它留在这里,以防其他人知道如何做到这一点,否则请投反对票...

英文:

I don't think you need the map. If I understand, after GetAll, you have two parallel slices, key and a. (I don't know GAE, but the _ raises my eyebrow. Is it something you should check?) Templates can handle parallel arrays. See in the doc how the range action can return two results, a value and and index. You should be able to range over one slice and use the index to get corresponding values from the other. It will be a more complex template, but should let you avoid the map.

Edit: Sorry, I thought I knew how to do this, but failed when I tried to code an example. I'll leave it here in case someone else knows how to do this, otherwise, downvote...

答案3

得分: 0

也许你可以将Key嵌入到Article中。你仍然需要循环遍历文章和键,但至少不需要创建一个单独的映射。

  1. type Article struct {
  2. // 将键添加到结构体中,但防止它保存到数据存储中。
  3. Key datastore.Key `datastore:"-"`
  4. }
  5. // 查询
  6. q := datastore.NewQuery("Article").Limit(10)
  7. // 定义用于检索实体的数组
  8. var a []Article
  9. // 检索实体
  10. key, _ := q.GetAll(c, &a)
  11. // 循环遍历文章并在遍历过程中添加键。
  12. for i := range a {
  13. a[i].Key = key[i]
  14. }
  15. template.Execute(w, map[string]interface{}{"Articles": a})

然后在你的模板中调用article.Key.Encode

英文:

Maybe you could embedding the Key in the Article. You would still have to loop over the articles and keys, but at least you wouldn't have to create a separate map.

  1. type Article struct {
  2. // Add a key to the struct, but prevent it from being saved to the datastore.
  3. Key datastore.Key `datastore:&quot;-&quot;`
  4. }
  5. // Query
  6. q := datastore.NewQuery(&quot;Article&quot;).Limit(10)
  7. // Define array where the entities will be retreived
  8. var a[] Article
  9. // Retreive entities
  10. key, _ := q.GetAll(c, &amp;a)
  11. // Loop through the articles adding the key as you go.
  12. for i := range a {
  13. a[i].Key = key[i]
  14. }
  15. template.Execute(w, map[string]interface{} { &quot;Articles&quot; : a})

Then in your template you would call article.Key.Encode

huangapple
  • 本文由 发表于 2012年4月30日 08:04:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/10377121.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定