首页 > 解决方案 > Couchbase N1QL 更新复杂结构的 JSON 文档

问题描述

介绍

你好!使用 Spring Startup Actuator 端点后,我收到了有关我的应用程序启动步骤的数据。这是一个 JSON 响应,我想对其进行一些修改,使其更具可读性。由于我在我的项目中使用 CouchBase,我认为它可能是修改具有复杂结构的大型 JSON 的最简单方法。我需要帮助编写 N1QL 查询来修改我的 JSON

先决条件

我有一个 JSON 文档,它的结构已加载到我的 CouchBase 中的存储桶中(我知道它很大,所以请您耐心等待并尝试理解它)

{
  "springBootVersion": "2.4.7",
  "timeline": {
    "startTime": {
      "nano": 909000000,
      "epochSecond": 1627565536
    },
    "events": [
      {
        "endTime": {
          "nano": 666000000,
          "epochSecond": 1627566426
        },
        "duration": {
          "seconds": 481,
          "nano": 751000000,
          "units": [
            "SECONDS",
            "NANOS"
          ],
          "negative": false,
          "zero": false
        },
        "startTime": {
          "nano": 666000000,
          "epochSecond": 1627566426
        },
        "startupStep": {
          "name": "spring.beans.instantiate",
          "id": 2480,
          "tags": [
            {
              "key": "beanName",
              "value": "hystrix-configuration"
            },
            {
              "key": "beanType",
              "value": "class org.apache.camel.model.HystrixConfigurationDefinition"
            },
            {
              "key": "exception",
              "value": "class org.springframework.beans.factory.NoSuchBeanDefinitionException"
            },
            {
              "key": "message",
              "value": "No bean named 'hystrix-configuration' available"
            }
          ],
          "parentId": 4
        }
      },
      {
        ...
      }
    ]
  }
}

问题

我需要的是按以下方式格式化该 JSON 文档:

  1. 我想排除字段“springBootVersion”、“时间线”,只留下“事件”对象数组。
  2. 在“events”数组中的每个对象中,我需要删除字段“startTime”、“endTime”和对象“duration”内部,我想删除字段“units”、“zero”、“negative”。
  3. 另外,如果可能的话,我想将字段纳秒修改为毫秒,方法是将其值除以 1 000 000 并将名称从“纳秒”更改为“毫秒”。
  4. 这可以是更新选择类型的查询,我不介意。
  5. (在我得到答案后添加)我还想按字段events.duration.secondsevents.duration.miliseconds对对象数组进行排序(如果 2 个对象的秒数相等)

期望的结果

修改 JSON 对象后的结果应该是这样的:

[
  {
    "duration": {
      "seconds": 481,
      "miliseconds": 751
    },
    "startupStep": {
      "name": "spring.beans.instantiate",
      "id": 2480,
      "tags": [
        {
          "key": "beanName",
          "value": "hystrix-configuration"
        },
        {
          "key": "beanType",
          "value": "class org.apache.camel.model.HystrixConfigurationDefinition"
        },
        {
          "key": "exception",
          "value": "class org.springframework.beans.factory.NoSuchBeanDefinitionException"
        },
        {
          "key": "message",
          "value": "No bean named 'hystrix-configuration' available"
        }
      ],
      "parentId": 4
    }
  },
  {
    ...secondOjbect
  },
  {
    ...ThirdOjbect
  }
]

我对 couchBase 和 N1QL 还很陌生,所以我只能更新结构简单的 JSON 对象。请寻求您的帮助。

*注意:如果您知道根据我的需要修改 JSON 的更简单、更简单的方法,请分享。

标签: jsonnosqlcouchbasen1ql

解决方案


SELECT 
   ARRAY {e.startupStep, 
          "duration":{e.duration.seconds, 
                      "miliseconds": e.duration.nanosconds/1000000
                     }
         } 
   FOR e IN d.timeline.events 
   END AS events
FROM default AS d
WHERE .......

如果你想更新 {"events":[ ]}

UPDATE default AS d
SET d = {"events": ARRAY {e.startupStep, 
                          "duration":{e.duration.seconds, 
                                      "milliseconds": e.duration.nanosconds/1000000
                                     }
                          } 
                   FOR e IN d.timeline.events 
                   END 
        }
WHERE .......

按秒对事件排序 ARRAY

SELECT (SELECT e.startupStep,
               {e.duration.seconds, milliseconds} AS duration
        FROM d.timeline.events AS e
        LET milliseconds = e.duration.nanosconds/1000000
        ORDER BY e.duration.seconds, milliseconds
       ) AS events
FROM default AS d
WHERE .......

推荐阅读