duanqilupinf67040 2016-06-23 18:57
浏览 26

如何使用子结构数组将JOIN映射到结构数组

I have two tables in my database, tags and record_tag:

tags
----
id
name

and

record_tag
----------
id
record_id
tag_id
...
tag_owner (user_id)

I have these two structs:

type Tag struct {
    Id          int    `json:"id" db:"id"`
    Tag_owner   string `json:"tag_owner" db:"tag_owner"`
    Tag_id      int    `json:"tag_id" db:"tag_id"`
    Record_id   string `json:"record_id" db:"record_id"`
    Record_type string `json:"record_type" db:"record_type"`
    Record_kind string `json:"record_kind" db:"record_kind"`
    Text        string `json:"text" db:"name"`
    Meta        string `json:"meta" db:"meta"`
}

type TaggedRecord struct {
    Record_id string `json:"record_id" db:"record_id"`
    Tags      []Tag  `json:"tags" db:"tag_id"`
}

And currently, I have this loop that performs n sqlx calls:

taggedRecords := []TaggedRecord{}
for _, record := range body.Records {
    tags := []Tag{}
    _ = db.Select(&tags, "SELECT r.id,r.tag_owner,r.record_id,r.tag_id,r.record_type,r.meta,r.record_kind,t.name FROM record_tag r, tags t WHERE r.tag_owner = $1 AND r.record_id = $2 AND r.tag_id = t.id", body.User, record)
    taggedRecord := TaggedRecord{Record_id: record, Tags: tags}
    taggedRecords = append(taggedRecords, taggedRecord)
}

When I marshall taggedRecords into JSON, I get this desired output:

[
  {
    "record_id": "dfwref3f",
    "tags": []
  },
  {
    "record_id": "3lkgekrljdkjfkjekjkjker",
    "tags": [
      {
        "id": 6,
        "tag_owner": "p0stman",
        "tag_id": 2,
        "record_id": "3lkgekrljdkjfkjekjkjker",
        "record_type": "candidate",
        "record_kind": "candidate",
        "text": "lol",
        "meta": "{\"name\": \"exxon mobile\"}"
      },
      {
        "id": 7,
        "tag_owner": "p0stman",
        "tag_id": 3,
        "record_id": "3lkgekrljdkjfkjekjkjker",
        "record_type": "candidate",
        "record_kind": "candidate",
        "text": "df",
        "meta": "{\"name\": \"exxon mobile\"}"
      }
    ]
  }
]

Obviously, this is dummy data. The above implementation works, but I don't like this it because usually n will be 10, and that's 10 separate network calls to database. I've poked around a little and tried a few things.. I feel like it should be possible to make this a single query. I've tried implementing this solution, but it does not work for me since my root struct embeds an array of child structs, not just a single child struct.

I have tried this:

taggedRecords := []TaggedRecord{}
var s string
for _, record := range body.Records {
    s = s + "r.record_id = '" + record + "' OR "
}
s = s[:len(s)-4]

_ := db.Select(&taggedRecords, "SELECT r.id,r.tag_owner,r.record_id,r.tag_id,r.record_type,r.meta,r.record_kind,t.name,t.id FROM record_tag r, tags t WHERE r.tag_owner = $1 AND "+s+" AND r.tag_id = t.id", body.User)

Select spits out an error saying can't find destination name id, which is I assume because there are two id fields coming at it, it can't map joins onto two structs correctly (the db syntax does not seem to support dots to denote table names or nicknames), or a mix of both.

Is it possible / what is the best way to implement this SQL call and marshal into the above output format while reducing database calls?

  • 写回答

1条回答 默认 最新

  • douzhan1238 2016-06-23 19:19
    关注

    You can use the IN expression to select a bunch of tags whole sale then assign them to their respective owners in Go.

      WHERE some_id IN(1,2,3,4)
    

    you can iterate through an array of ids to build it

    Or you can avoid ambiguous queries by using SQL aliases

     SELECT t.id , r.id as r_id 
    

    And discriminates these columns in Go , in multiple ways( add a column to a struct, use sqlx struct tags ...)

    评论

报告相同问题?

悬赏问题

  • ¥15 孟德尔随机化结果不一致
  • ¥20 求用stm32f103c6t6在lcd1206上显示Door is open和password:
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法