PostgreSQL jsonb更新多个嵌套字段

PostgreSQL jsonb更新多个嵌套字段,sql,postgresql,scala,scalikejdbc,Sql,Postgresql,Scala,Scalikejdbc,I在postgresql数据库中具有id字段和jsonb字段的表。jsonb的结构如下所示: { "id": "some-id", "lastUpdated": "2018-10-24T10:36:29.174Z", "counters": { "counter1": 100, "counter2": 200 } } 我需要做的是更新lastModified和其中一个计数器: def update(id: String, coun

I在postgresql数据库中具有
id
字段和
jsonb
字段的表。jsonb的结构如下所示:

{
    "id": "some-id",
    "lastUpdated": "2018-10-24T10:36:29.174Z",
    "counters": {
        "counter1": 100,
        "counter2": 200
    }
}
我需要做的是更新
lastModified
和其中一个计数器:

def update(id: String, counter: Option[String])
因此,例如,如果我执行
update(“some id”,some(“counter2”)
操作,我需要
lastUpdated
作为当前日期时间,并且
counter2
增加到
201

我使用的是ScalikeJDBC,这就是我到目前为止取得的成果:

def update(id: String, counter: Option[String]): Option[ApiKey] = DB localTx { implicit session =>

val update =
  if(counter.isDefined)
    sqls"""'{"lastUpdated": ${DateTime.now()}, "counters": {'${counter.get}: COALESCE('counters'->>${counter.get},'0')::int'}'"""
  else
    sqls"""'{"lastUpdated": ${DateTime.now()}}'"""

sql"UPDATE apiKey SET content = content || $update WHERE id = $key".update().apply()
}
但我得到了以下错误:

org.postgresql.util.PSQLException:列索引超出范围:4,列数:3

我尝试过其他方法,但没能成功。是否可以将其作为单个查询编写


下面是一个帮助测试的小把戏

我对PostgreSQL的
jsonb
类型了解不多,但似乎不可能在JDBC PreparedStatement中将所有内容作为绑定参数传递。我不得不说,您可能必须使用SQLSyntax.createUnsafely绕过PreparedStatement,如下所示:

def update(id: String, counter: Option[String]): Unit = DB localTx { implicit session =>
  val now = java.time.ZonedDateTime.now.toOffsetDateTime.toString
  val q: SQLSyntax = counter match { 
    case Some(c) => 
      val content: String =
        s"""
        jsonb_set(
            content || '{"lastUsed": "${now}"}',
            '{counters, $c}',
            (COALESCE(content->'counters'->>'$c','0')::int + 1)::text::jsonb
        )
        """
      SQLSyntax.createUnsafely(s"""
    UPDATE
        example
    SET
        content = ${content}
    WHERE
        id = '$id';
    """)
    case _ => 
      throw new RuntimeException
  }
  sql"$q".update.apply()
}
update("73c1fa11-bf2f-42c9-80fd-c70ac123fca9", Some("counter2"))

我没有使用ScalikeJDBC的经验,但是Postgres查询可以是这样的:或者可能是这样,为了摆脱double
jsonb\u集
调用:
|
的问题是它没有进行递归合并。这很有意义,我会尝试一下,谢谢!一个只有在更新存在时才更新嵌套计数器的版本:我意识到我不能真正回答你的问题,因为我不知道ScalikeJDBC是如何工作的,但我希望它能有所帮助。事实上,这非常有用,因为我终于写了一个符合我要求的查询:不幸的是,我仍然无法在Scalike中工作,但这只是一个开始。