8

キーがネストされていることがある JSONB フィールドがあります。例:

{"nested_field": {"another URL": "foo", "a simple text": "text"},
 "first_metadata": "plain string",
 "another_metadata": "foobar"}

私が行った場合

.filter(TestMetadata.metadata_item.has_key(nested_field))

このレコードを取得します。

ネストされたキーの存在を検索するにはどうすればよいですか? ( "a simple text")

4

2 に答える 2

16

SQLAlchemy を使用すると、テスト文字列に対して次のように動作するはずです。

class TestMetadata(Base):
    id = Column(Integer, primary_key=True)
    name = Column(String)
    metadata_item = Column(JSONB)

のSQLAlchemyドキュメントJSONBに従って(パスインデックス操作の例を検索):

expr = TestMetadata.metadata_item[("nested_field", "a simple text")]
q = (session.query(TestMetadata.id, expr.label("deep_value"))
     .filter(expr != None)
     .all())

SQLこれにより、以下が生成されます。

SELECT  testmetadata.id AS testmetadata_id, 
        testmetadata.metadata_item #> %(metadata_item_1)s AS deep_value
FROM    testmetadata
WHERE  (testmetadata.metadata_item #> %(metadata_item_1)s) IS NOT NULL
-- @params: {'metadata_item_1': u'{nested_field, a simple text}'}
于 2015-02-03T20:27:12.050 に答える
1

このクエリは、入れ子になった JSON オブジェクトを operator で抽出した後、入れ子になったフィールドの存在を?operatorでテストします。->

SELECT EXISTS (
   SELECT 1 
   FROM   testmetadata
   WHERE  metadata_item->'nested_field' ? 'a simple text'
   );

プレーンな GIN インデックスはこのクエリをサポートしていないことに注意してください。これを高速化するには、式インデックスが必要です。metadata_item->'nested_field'

CREATE INDEX testmetadata_special_idx ON testmetadata
USING gin ((metadata_item->'nested_field'));

同様のケースのマニュアルに例があります。

于 2015-02-03T20:09:05.447 に答える