SQLAlchemy 根据 JSONB 中的嵌套键进行过滤
SQLAlchemy filter according to nested keys in JSONB
我有一个有时包含嵌套键的 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"
)
此查询测试嵌套字段是否存在 ?
operator, after extracting the nested JSON object with the ->
operator:
SELECT EXISTS (
SELECT 1
FROM testmetadata
WHERE metadata_item->'nested_field' ? 'a simple text'
);
请注意,普通 GIN 索引不支持此查询。您需要在 metadata_item->'nested_field'
上添加一个 expression index 才能加快速度。
CREATE INDEX testmetadata_special_idx ON testmetadata
USING gin ((metadata_item->'nested_field'));
有一个类似案例example in the manual。
对于 SQLAlchemy,以下应该适用于您的测试字符串:
class TestMetadata(Base):
id = Column(Integer, primary_key=True)
name = Column(String)
metadata_item = Column(JSONB)
根据SQLAlchemy documentation of 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}'}
我有一个有时包含嵌套键的 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"
)
此查询测试嵌套字段是否存在 ?
operator, after extracting the nested JSON object with the ->
operator:
SELECT EXISTS (
SELECT 1
FROM testmetadata
WHERE metadata_item->'nested_field' ? 'a simple text'
);
请注意,普通 GIN 索引不支持此查询。您需要在 metadata_item->'nested_field'
上添加一个 expression index 才能加快速度。
CREATE INDEX testmetadata_special_idx ON testmetadata
USING gin ((metadata_item->'nested_field'));
有一个类似案例example in the manual。
对于 SQLAlchemy,以下应该适用于您的测试字符串:
class TestMetadata(Base):
id = Column(Integer, primary_key=True)
name = Column(String)
metadata_item = Column(JSONB)
根据SQLAlchemy documentation of 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}'}