问题
I have a Postgres JSONB field, with some nested arrays and other objects.
from sqlalchemy.dialects.postgresql import JSONB
class Family(db.Model):
meta = db.Column(JSONB)
joes = Family(meta=[
{
"name": "Joe",
"children": [
{
"name": "Jane"
},
{
"name": "Kate"
}
]
},
{
"name": "Lisa",
"children": [
{
"name": "Mary"
},
{
"name": "David"
}
]
},
])
Is there a way to query all the kids with a certain substring in their names?
If I want to query for 'a'
it should get me Mary, David, Kate, Jane
.
I was thinking, maybe something like
Family.query.filter(
Family.meta.contains([{"children": [{"name": func.contains("a")}]}])
)
回答1:
The trick is to unnest the array or arrays using jsonb_array_elements(), and then filter:
meta_value = literal_column('meta.value', type_=JSONB)
children_value = literal_column('children.value', type_=JSONB)
Family.query.\
with_entities(children_value['name'].astext).\
select_from(
Family,
func.jsonb_array_elements(Family.meta).alias('meta'),
func.jsonb_array_elements(
meta_value['children']).alias('children')).\
filter(children_value['name'].astext.contains('a'))
Note the use of literal_column() to reference the values of the set returning function jsonb_array_elements().
来源:https://stackoverflow.com/questions/54669900/sqlalchemy-filter-nested-jsonb-within-arrays