【问题标题】:How to filter JSON array elememts by type of value?如何按值类型过滤 JSON 数组元素?
【发布时间】:2023-03-26 02:42:01
【问题描述】:

Postgres 12,列包含来自 Quill 编辑器的 sample json,例如:

{
    "ops": 
    [
    {
        "insert": "Text 1"
    }, 
    {
        "insert": {"video":"..."}
    },
    {
        "insert": "Text 2"
    }, 
    {
        "insert": {"image":"data:image/jpeg;base64,..."}
    }]
}

要获得Text 1 Text 2 的结果,意味着过滤掉(忽略/跳过)所有"insert": {"video":"..."}"insert": {"image":"..."}(如果出现)。

检查::json ?| array['video', 'image'] 或删除::jsonb-'video' 之类的操作员似乎很有帮助,但 pg 不做单行 if-then-else (condition)?true_value:false_value。如何在这个函数中使用它们?

CREATE OR REPLACE FUNCTION public.fun(
    j json)
    RETURNS text
    LANGUAGE 'plpgsql' immutable
AS $BODY$
begin
  return string_agg((obj->>'insert') || ' ', '')
  FROM json_array_elements(j->'ops') obj;
end;
$BODY$;

【问题讨论】:

    标签: json postgresql


    【解决方案1】:

    这取决于您要从与键 "ops" 关联的 json 数组值中识别和选择元素 {"insert": "Text 1"}{"insert": "Text 2"} 的方式:

    通过元素在 json 数组中的位置来识别和选择元素:

      return j#>>'{ops,0,insert}' || ' ' || j#>>'{ops,2,insert}' ;
    

    通过 json 类型(即“字符串”)识别并选择元素:

      return string_agg(obj->>'insert', ' ')
      FROM json_array_elements(j->'ops') obj
      WHERE json_typeof(obj) = 'string' ;
    

    通过非“对象”的 json 类型识别和选择元素:

      return string_agg(obj->>'insert', ' ')
      FROM json_array_elements(j->'ops') obj
      WHERE NOT json_typeof(obj) = 'object' ;
    

    最后一个示例不选择值为 json 对象的元素,无论此 json 对象中的“键”和“值”是什么。

    【讨论】:

    • 感谢您的意见。提供的数据是一个示例,videoimage 可以在任何地方,也可以不存在。
    • 好的,那么您在与“ops”键关联的 json 数组中选择 json 对象的标准是什么?
    • 过滤掉(忽略)所有"insert": {"video":"..."}"insert": {"image":"..."},上面示例的结果将是Text 1 Text 2
    • @EdouardH。我意识到你很亲密。只是错过了一层嵌套。
    • @EdouardH。你很亲密,谢谢。
    【解决方案2】:
    CREATE OR REPLACE FUNCTION public.fun(j json)
      RETURNS text
      LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
    $func$
    SELECT string_agg(elem ->> 'insert', ' ')
    FROM   json_array_elements(j -> 'ops') elem
    WHERE  json_typeof(elem->'insert') <> 'object';
    $func$;
    

    db小提琴here

    像您已经使用json_array_elements() 一样取消嵌套后,使用json_typeof() 检查属性名称“插入”的类型(不适用于嵌套对象,它始终是一个对象)。

    我使用一个简单的 SQL 函数来完成简单的任务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-04
      • 2020-03-17
      • 2012-09-17
      • 2022-01-18
      • 1970-01-01
      • 2020-11-23
      • 2021-12-17
      • 2020-09-10
      相关资源
      最近更新 更多