如何将 JOIN 映射到具有子结构数组的结构数组

Posted

技术标签:

【中文标题】如何将 JOIN 映射到具有子结构数组的结构数组【英文标题】:How to map a JOIN onto an array of structs with a child array of structs 【发布时间】:2016-10-26 06:20:01 【问题描述】:

我的数据库中有两个表,tagsrecord_tag

tags
----
id
name

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

我有这两个结构:

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"`

目前,我有这个循环执行 n sqlx 调用:

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 := TaggedRecordRecord_id: record, Tags: tags
    taggedRecords = append(taggedRecords, taggedRecord)

当我将 taggedRecords 编组为 JSON 时,我得到了所需的输出:

[
  
    "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\""
      
    ]
  
]

显然,这是虚拟数据。上面的实现有效,但我不喜欢这样,因为通常n 将是 10,这是对数据库的 10 个单独的网络调用。我已经四处摸索并尝试了一些事情。我觉得应该可以将其作为一个查询。我已经尝试实现 this 解决方案,但它对我不起作用,因为我的根结构嵌入了一个 array 子结构,而不仅仅是一个子结构。

我试过这个:

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 吐出一个错误,说找不到目标名称 id,我假设这是因为有两个 id 字段,它不能正确地将连接映射到两个结构(db 语法确实似乎不支持用点来表示表名或昵称),或两者兼而有之。

在减少数据库调用的同时,实现此 SQL 调用并编组为上述输出格式是否可能/最好的方法是什么?

【问题讨论】:

【参考方案1】:

您可以使用 IN 表达式选择一堆标签整体销售然后 在 Go 中将它们分配给各自的所有者。

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

您可以遍历一个 id 数组来构建它

或者您可以使用 SQL 别名来避免不明确的查询

 SELECT t.id , r.id as r_id 

并在 Go 中以多种方式区分这些列(将列添加到结构,使用 sqlx 结构标签...)

【讨论】:

以上是关于如何将 JOIN 映射到具有子结构数组的结构数组的主要内容,如果未能解决你的问题,请参考以下文章

C 定义的结构数组的元素在编译为 C++ 时具有不完整的类型

无法将固定大小的字节数组从结构复制到 C# 结构中的另一个数组

如何从 Rust 中的结构数组中获取字段值数组?

如何将带有嵌套数组的 JSON 对象映射到打字稿模型中?

Numpy - 将具有第一行的csv作为名称立即加载到结构化数组中?

Numpy - 将具有第一行的csv作为名称立即加载到结构化数组中?