【发布时间】:2021-06-15 23:00:04
【问题描述】:
我正在尝试用 Go 重写我们系统的某些部分。它们目前是用 Python 编写的。我想要服务的一些数据存在于 Elasticsearch 中。
在我们的用户中,我们有一些标准字段,但也允许人们创建一些特定于其环境的自定义字段。例如,我们有一个产品对象,它有一些常见的字段,如 name 和 price,但我们让某人创建一个像 discount_price 或 requires_freight 这样的字段来同意他们的用例。
在 Python 中,这很容易适应。读入 JSON,我们选择的 JSON 解析器会进行一些合理的类型推断,然后我们可以在处理完数据后返回。
在 Go 中,我们想要处理来自 Elasticsearch JSON 响应的任何数据都必须映射到一个类型。或者至少这是我的理解。例如:
import (
"encoding/json"
)
...
type Product struct {
Name string `json:"name"`
Price string `json:"price"`
}
以下是数据可能外观的简化示例。我已经在我想通过的非标准字段的名称前加上custom:
{
"id": "ABC123",
"name": "Great Product",
"price": 10.99,
"custom_alternate_names": ["Great Product"],
"custom_sellers": [{
"id": "ABC123",
"name": "Great Product LLC",
"emails": ["great@stuff.com"]
}]
}
对于路由实际需要处理或操作自定义字段的地方的特殊情况是可以的。但在大多数情况下,通过 JSON 数据保持不变就可以了,因此我们没有为了安全而强加任何类型映射的事实并没有添加任何东西。
有没有办法设置struct 的接口(?)可以作为任何未映射字段的传递?或者在返回数据之前获取未解析的 JSON 数据并与映射对象重新组合的方法?
【问题讨论】:
-
您可以将
json.RawMessage用于您只想写入/读取并且不需要操作和/或验证的数据。对于您确实需要操作的自定义字段,您可以使用映射或切片,并且映射/切片的元素类型可以是具有 3 个成员 fieldName、fieldType、fieldValue 的结构。 -
这很有帮助。然后我将如何将包罗万象添加到结构中?抱歉,这是一个愚蠢的问题——我对 Go 还很陌生。
-
取决于 json,自定义字段是否与非自定义字段处于同一级别(嵌套),例如
{"name":"...","price":"...","custom_field1":"...","custom_field2":"..."}?或者它们是否组合在一起并嵌套在某个预定义字段下,即{"name":"...","price":"...","custom":{"field1":"...","field2":"..."}}?还是更复杂?如果可以,请通过添加您要处理的 json 示例来更新问题。 -
嵌套是不均匀的,但我认为它只能深入两层。我将挖掘一个可共享的示例并更新问题。
-
在问题中添加了我认为非常有代表性的例子。
标签: json go elasticsearch