简体   繁体   English

SQLAlchemy根据JSONB中的嵌套键进行过滤

[英]SQLAlchemy filter according to nested keys in JSONB

I have a JSONB field that sometimes has nested keys. 我有一个JSONB字段,有时有嵌套键。 Example: 例:

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

If I do 如果我做

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

I get this record. 我得到了这个记录。

How can I search for existence of the nested key? 如何搜索嵌套密钥的存在? ( "a simple text" ) "a simple text"

With SQLAlchemy the following should work for your test string: 使用SQLAlchemy,以下内容适用于您的测试字符串:

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

as per SQLAlchemy documentation of JSONB (search for Path index operations example): 根据JSONB SQLAlchemy文档 (搜索Path索引操作示例):

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

which should generate the SQL below: 哪个应生成以下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}'}

This query tests for existence of the nested field with the ? 此查询测试是否存在嵌套字段? operator , after extracting the nested JSON object with the -> operator : 运算符 ,在使用->运算符提取嵌套的JSON对象之后:

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

Note that a plain GIN index does not support this query. 请注意,普通GIN索引不支持此查询。 You would need an expression index on metadata_item->'nested_field' to make this fast. 您需要在metadata_item->'nested_field'上使用表达式索引才能使其快速。

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

There is an example in the manual for a similar case. 手册中有一个类似案例的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM