【问题标题】:Can't create an index on a jsonb field with date无法在带有日期的 jsonb 字段上创建索引
【发布时间】:2019-11-15 12:54:30
【问题描述】:

我在表中有一个 jsonb 列 event。我正在尝试创建索引

CREATE INDEX ON table(((events->'START'->> 'date')::timestamp AT TIME ZONE 'PST'));

但它抛出错误functions in index expression must be marked IMMUTABLE

在传递一个时区后,它应该使其不可变,但我不确定为什么它仍然会抛出错误。

【问题讨论】:

标签: postgresql jsonb database-indexes


【解决方案1】:

timestamp 的演员表是你的问题。不是IMMUTABLE,因为使用的函数接受now 之类的参数。

如果您确定您的数据仅包含常规时间戳而不包含此类值,您可以定义自己的 IMMUTABLE LANGUAGE sql 函数来包装类型转换。

您可以在查询中使用这样的函数并为其编制索引。如果某些值的强制转换确实不是不可变的,那么您的索引将会损坏。

【讨论】:

    【解决方案2】:

    用我自己的增强 Laurenz Albe 的答案以便能够发布代码,我正在使用以下内容。

    假设您有一个表mytable,其JSONB 字段为thedata,其中包含{ "datetime": "2020-03-21T33:44:55.193843281Z ", ... } 之类的数据:

    -- Create immutable UTC parsing function, see:
    -- * https://stackoverflow.com/questions/58877503/cant-create-an-index-on-a-jsonb-field-with-date
    -- * https://stackoverflow.com/questions/5973030/error-functions-in-index-expression-must-be-marked-immutable-in-postgres
    -- It parses dates of format:
    --     YYYY-MM-DDTHH:MM:SSZ
    -- (with a 'T' between date and time, and a 'Z' at the end) for example:
    --     2020-03-21T33:44:55Z
    --     2020-03-21T33:44:55.193843281Z
    
    CREATE OR REPLACE FUNCTION utc_to_timestamp(some_time text)
      RETURNS timestamp with time zone
    AS
    $BODY$
        select to_timestamp($1, 'YYYY-MM-DD"T"HH24:MI:SS"Z"');
    $BODY$
    LANGUAGE sql
    IMMUTABLE;
    
    -- Define the index:
    CREATE INDEX mytable_expr_datetime on mytable (utc_to_timestamp(the_data ->> 'datetime'));
    

    因此,对于您问题中的表/字段名称,您必须将the_data ->> 'datetime' 替换为events->'START'->> 'date',并将mytable 替换为events

    【讨论】:

      猜你喜欢
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多