序文
postgresのjsonbフィールドはクエリをサポートしており、ツリー構造であるため、クエリ速度は悪くありません。特定のフィールドの値のクエリは次のように記述されていることがわかっています。
- username = klingのレコードをクエリします
where raw::jsonb ->> 'username' = 'kling'
では、jsonbフィールドで深さが不明なサブフィールドクエリをサポートするにはどうすればよいですか?例:
- 張三という名前のクラスの先生の記録を照会します
where (raw::jsonb ->> class)::jsonb ->> 'master_name' = '张三'
深さも非常に長いです。
成し遂げる:
// 生成动态的jsonb查询条件,不支持对子字段为数组的数据进行查询
// 条件:
// chain json字段链长度最少为2,其中第一个参数为主表字段,后面的参数为子字段
// condition 必须为数据库支持的条件判断符号
// value 为数据库支持的正常值
// 示例:
// chain = []string{"raw", "zonst_vx", "game_id}
// condition = "="
// value = "5"
// 输出: ((raw)::jsonb ->>'zonst_vx')::jsonb ->>'game_id'='5'
func JSONBWhere(chain []string, condition string, value string) (string) {
return fmt.Sprintf("%s%s'%s'", countJSONB(chain), condition, value)
}
func point(field string, subfield string) string {
return fmt.Sprintf("(%s)::jsonb ->>'%s'", field, subfield)
}
func countJSONB(chain []string) string {
if len(chain) == 2 {
return point(chain[0], chain[1])
}
sub := chain[:len(chain)-1]
last := chain[len(chain)-1]
return point(countJSONB(sub), last)
}
例:
func TestJSONWhere(t *testing.T) {
fmt.Println(JSONBWhere([]string{
"raw", "zonst_vx", "game_id"}, "=", "5"))
}
出力:
((raw)::jsonb ->>'zonst_vx')::jsonb ->>'game_id'='5'
実際の使用
- 青い
type JSONQuery struct{
Enable bool `json:"enable"`
FieldName string `json:"field_name"`
Condition string `json:"condition"`
Value string `json:"value"`
}
var jsonQuery = JSONQuery{
Enable: true,
FieldName: "raw.class.master_name",
Condition: "=",
Value: "张三",
}
if jsonQuery.Enable {
db.Where(JSONBWhere(
strings.Split(jsonQuery.FieldName, "."),
jsonQuery.Condition,
jsonQuery.Value,
))
}