Postgres 9.4でJSON配列要素でjson_to_recordを使用すると、「エラー:不正な形式の配列リテラル」


9

これは問題をうまく説明しています:

列bがテキストではなく配列である場合、次のように機能します。

select * 
from json_to_record('{"a":1,"b":["hello", "There"],"c":"bar"}') 
    as x(a int, b text, d text);

 a |         b          | d
---+--------------------+---
 1 | ["hello", "There"] |

しかし、b列を配列として定義すると、次のエラーが発生します。

select * 
from json_to_record('{"a":1,"b":["hello", "There"],"c":"bar"}') 
    as x(a int, b text[], d text)

ERROR:  malformed array literal: "["hello", "There"]"
DETAIL:  "[" must introduce explicitly-specified array dimensions.

JSON配列をターゲット列タイプのPostgres配列に変換するようにどのように説得/強制json_to_record(またはjson_populate_record)できますか?

回答:


6

クリスの答えのほんの少しのバリエーション:

SELECT a, translate(b, '[]', '{}')::text[] AS b, d
FROM json_to_record('{"a": 1, "b": ["hello", "There"], "c": "bar"}')
AS x(a int, b text, d text);

考え方は同じです。JSON配列を配列にマッサージします。この場合は、配列リテラルを使用します。少しすっきりしたコードに加えて(私はそれが好きですが、正規表現は通常、この点ではあまり役に立ちません)、それも少し速く見えます:

CREATE TABLE jsonb_test (
    id serial,
    data jsonb
);

INSERT INTO jsonb_test (id, data)
SELECT i, format('{"a": %s, "b": ["foo", "bar"], "c": "baz"}', i::text)::jsonb 
FROM generate_series(1,10000) t(i);

SELECT a, string_to_array(regexp_replace(b, '\[*\"*\s*\]*','','g'),',') AS b, d
FROM jsonb_test AS j, 
LATERAL json_to_record(j.data::json) AS r(a int, b text, d text);

-- versus 

SELECT a, translate(b, '[]', '{}')::text[] AS b, d
FROM jsonb_test AS j, 
LATERAL json_to_record(j.data::json) AS r(a int, b text, d text);

このデータセットと私のテストボックスでは、正規表現バージョンは300ミリ秒の平均実行時間を示していますが、私のバージョンは210ミリ秒を示しています。


1

これは最もエレガントなソリューションではないかもしれませんが、問題を解決します...

SELECT a,string_to_array(regexp_replace(b, '\[*\"*\s*\]*','','g'),',') AS b,d
FROM json_to_record('{"a":1,"b":["hello", "There"],"c":"bar"}')
AS x(a int, b text, d text);

それがどのように機能するかは非常に簡単です:

まず、でtext文字列をb取得し、有用な情報まで削除します。これはregexp_replace()as を使用して行われます

regexp_replace(b, '\[*\"*\s*\]*','','g')

すべてのインスタンスを削除するには["]、および空白文字は、またはより具体的には、これらの文字のすべてのインスタンスを置き換えるために''、フラグを使用して、これは世界的に、合図適用します'g'

次に、単純にstring_to_array()as を使用して文字列を配列に分割します

string_to_array(your_string,',')

この場合your_string、単に上記の結果ですregexp_replace()。2番目の引数','string_to_array()、項目がコンマ区切りであることを示しています。

これにより、text[]目的のエントリを含むフィールドが生成されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.