69

TEXT有効な JSON 文字列を含む列があります。

CREATE TABLE users(settings TEXT);

INSERT INTO users VALUES ('{"language":"en","gender":"male"}');
INSERT INTO users VALUES ('{"language":"fr","gender":"female"}');
INSERT INTO users VALUES ('{"language":"es","gender":"female"}');
INSERT INTO users VALUES ('{"language":"en","gender":"male"}');

一部のフィールドをクエリ可能な形式に変換したいと考えています。

REGEXP_REPLACE各フィールドの Aが行います (languageフィールドとgenderフィールド)。しかし、それは有効な JSON であるため、次の方法があります。

  • JSON型に変換
  • hstore 型に変換
  • または他の実行可能な方法

SQLFiddle: http://sqlfiddle.com/#!12/54823

4

7 に答える 7

75
SELECT cast(settings AS json) from users;

7年後に編集

データが非構造化されていない限り、非構造化列を使用しないことを強くお勧めします。RDBMS は非常に長い道のりです。私たちはかなり大きなプラットフォームを構築し、ユーザー設定を json 列として使用しましたが、最終的にはジャンク ドロワーになり、何年も後にクリーンアップする必要がありました

于 2014-04-17T01:11:22.087 に答える
69

または、Reza よりも最短の方法で:

SELECT settings::json FROM users;

次に、たとえば言語を選択するには:

SELECT settings::json->>'language' FROM users;

詳細については、公式ドキュメントを参照してください。

于 2014-10-02T07:58:15.087 に答える
4

::jsonb列が既に json であり、ルート レベルに文字列が含まれている場合は機能しません。このような文字列を JSON に変換する 1 つのライナーを次に示します。

SELECT (settings #>> '{}')::jsonb -> 'language' from users;

私はここでこの答えを見つけました

#>>このステートメントは、最初に空のパスが指定された演算子を使用して、ルート レベルの文字列をテキストとして抽出します。このような文字列をテキスト ( ) に単純にキャストする::textと、すべての引用符がエスケープされるため、機能しないことに注意してください。次に、このように抽出された文字列が json オブジェクト ( ::jsonb) に解析されます。

このクエリの代替バージョンは、json 文字列を配列に入れ、最初の要素をテキストとして抽出することです。

キャスト(json_build_array(設定)->> 0 as json)を選択します

この問題を解決するには、次のコマンドを使用して、ルート レベルの文字列を含むすべてのフィールドを json に変換することもできます。

UPDATE users
SET
    settings = settings #>>'{}'::jsonb
WHERE settings ->> 'language' is  NULL
于 2021-08-06T09:47:41.407 に答える
3

インデックスが必要な場合は、json を入力として受け取り、必要なフィールドを pl 言語で出力する不変関数を作成します。

create function extract_language(text) returns text as $$
  -- parse $1 as json
  -- return $1.language
$$ language whatever immutable;

次に、式にインデックスを追加します。

create index users_language on users(extract_language(settings));

インデックスは、(潜在的に) 次のようなクエリで使用されます。

select * from users where extract_language(settings) = 'en';
于 2013-04-27T09:12:02.287 に答える