草庐IT

json - 编码结构时用嵌入式 json 替换 ObjectId

coder 2023-06-27 原文

我正在使用 Go 和 MongoDB 构建 RESTful API,但在将一个文档的 JSON 嵌入另一个文档的 JSON 时遇到了一些困难。这是我要完成的玩具示例。我有以下架构:

type Post struct {
    ID    bson.ObjectId `json:"id,omitempty"`
    Title string        `json:"title,omitempty"`
    Owner bson.ObjectId `json:"owner,omitempty"` // references a User
}

type User struct {
    ID   bson.ObjectId `json:"id,omitempty"`
    Name string        `json:"name,omitempty"`
}

在为帖子创建 JSON 时,我想首先在 MongoDB 中查找帖子的所有者,并将生成的用户嵌入到该帖子的 JSON 中(代替原始 ObjectId ), 像这样:

{
    "id": "...",
    "title": "My awesome post",
    "owner": {
        "id": "...",
        "name": "Cody"
    }
}

除了使用 map[string]interface{} 手动构建 JSON 之外,我不太确定如何完成此操作,如下所示:

post := LookupPost(...)
user := LookupUser(post.Owner)

m := map[string]interface{}{
    "id": post.ID,
    "title": post.Title,
    "owner": map[string]interface{}{
        "id": user.ID,
        "name": user.Name,
    },
}

b, _ := json.Marshal(m)

显然,这个 扩展性不是很好 不是很干——理想情况下,我可以在每个结构定义中使用 json 标签,并且自动插入的字段。

我是否遗漏了什么,或者我正在尝试做的事情是不可能的?或者我只是没有正确地使用 Go 中的 MongoDB/JSON?换句话说,我来自 Node.js 背景,在这种情况下,这类功能微不足道。

编辑

为了澄清一些事情,这里有一些不正确的 Go 代码显示了我想做的事情

func getPostJSON() []byte {
    p := LookupPost(...)
    u := LookupUser(p.Owner, ...)

    uj, _ := json.Marshal(u)
    p.Owner = uj // can't do this in Go

    pj, _ := json.Marshal(p)

    return pj
}

最佳答案

我不熟悉 MongoDB 或 bson.ObjectId,但是你能用你自己的类型替换你的 User 字段并让 MongoDB 轻松地为你填写吗?用户的 bson.ObjectId?

如果是这样,您可以将用户对象 ID 包装到他们自己的实现 json.Marshaler 接口(interface)的类型中。例如:

// Embedded (instead of `type x bson.ObjectId`) so that we
// get all the methods and satisfy all the interfaces that
// bson.ObjectId does. Hopefully that's engough to allow MongoDB
// to fill in fields of this type from a database??
type ownerObjID struct{ bson.ObjectId }

// Here we marshal the results of looking up the user from the id
// rather than just the ID itself.
func (oid ownerObjID) MarshalJSON() ([]byte, error) {
    user, err := LookupUser(oid.ObjectId)
    if err != nil {
        return nil, err
    }
    return json.Marshal(user)
}

type Post struct {
    ID    bson.ObjectId `json:"id,omitempty"`
    Title string        `json:"title,omitempty"`
    Owner ownerObjID    `json:"owner,omitempty"` // <-- is this type wrapping doable/easy with MongoDB?
}

type User struct {
    ID   bson.ObjectId `json:"id,omitempty"`
    Name string        `json:"name,omitempty"`
}

func main() {
    post := LookupPost()
    b, err := json.MarshalIndent(post, "", "  ")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("JSON:\n%s\n", b)
}

// Some stubs for demo:
func LookupPost() Post {
    return Post{
        ID:    "postID001",
        Title: "Ima Test",
        Owner: ownerObjID{"ownerID002"},
    }
}

func LookupUser(id bson.ObjectId) (User, error) {
    return User{
        ID:   id,
        Name: "name for " + string(id),
    }, nil
}

Playground

给我:

JSON:
{
  "id": "postID001",
  "title": "Ima Test",
  "owner": {
    "id": "ownerID002",
    "name": "name for ownerID002"
  }
}

关于json - 编码结构时用嵌入式 json 替换 ObjectId,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30611086/

有关json - 编码结构时用嵌入式 json 替换 ObjectId的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  3. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  4. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  5. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  6. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  7. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  8. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  9. ruby-on-rails - 如何使用 Rack 接收 JSON 对象 - 2

    我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":

  10. ruby-on-rails - 一般建议和推荐的文件夹结构 - Sinatra - 2

    您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应

随机推荐