JSON 查询语法对比
下面是一个更复杂的 JSON 查询示例,展示了如何在 MongoDB、PostgreSQL、jq 和 JMESPath 以及JSONPath中进行查询。假设我们有一个更深层次的 JSON 数据结构:
假设 JSON 数据如下:
{
"store": {
"book": [
{
"category": "fiction",
"author": "J.K. Rowling",
"title": "Harry Potter",
"price": 29.99,
"publisher": {
"name": "Bloomsbury",
"location": "London"
},
"reviews": [
{ "user": "John", "rating": 5 },
{ "user": "Alice", "rating": 4 }
]
},
{
"category": "fiction",
"author": "J.R.R. Tolkien",
"title": "The Hobbit",
"price": 19.99,
"publisher": {
"name": "HarperCollins",
"location": "New York"
},
"reviews": [
{ "user": "Bob", "rating": 4 },
{ "user": "Charlie", "rating": 3 }
]
},
{
"category": "non-fiction",
"author": "Yuval Noah Harari",
"title": "Sapiens",
"price": 14.99,
"publisher": {
"name": "HarperCollins",
"location": "New York"
},
"reviews": [
{ "user": "David", "rating": 5 },
{ "user": "Emma", "rating": 4 }
]
}
],
"bicycle": {
"color": "red",
"price": 199.99
}
}
}
查询要求:
- 查找所有价格大于 20 的书籍。
- 查找出版社是 "HarperCollins" 且评分超过 4 的书籍。
- 查找书籍的价格,并返回对应的出版社名称。
MongoDB 查询
MongoDB 查询语法可以非常灵活。假设你要查询价格大于 20 且出版社为 "HarperCollins" 的书籍,并且书籍的平均评分要大于 4:
db.store.find({
"book": {
"$elemMatch": {
"price": { "$gt": 20 },
"publisher.name": "HarperCollins",
"reviews.rating": { "$gt": 4 }
}
}
})
PostgreSQL 查询
在 PostgreSQL 中,假设数据存储在一个 jsonb
字段中,我们可以查询价格大于 20 的书籍,并且查询符合特定出版社名称和评分条件的书籍:
SELECT *
FROM your_table
WHERE
jsonb_array_elements(data->'store'->'book')
@> '{"price": 19.99}'
AND
jsonb_extract_path_text(
jsonb_array_elements(data->'store'->'book'),
'publisher', 'name'
) = 'HarperCollins'
AND
jsonb_array_elements(data->'store'->'book'->'reviews')
@> '{"rating": 5}';
jq 查询
jq 查询语言可以非常简洁,以下是查找价格大于 20 且出版社为 "HarperCollins" 且至少有一个评论评分大于 4 的书籍:
jq '.store.book[] | select(.price > 20 and .publisher.name == "HarperCollins" and (.reviews[] | .rating > 4))' input.json
Python JMESPath 查询
在 Python 中使用 JMESPath 库查询价格大于 20 且评论评分大于 4 的书籍,并返回出版社名称:
import jmespath
data = …
result = jmespath.search(
'store.book[?price > `20` && publisher.name == `HarperCollins` && reviews[?rating > `4`]]',
data
)
print(result)
JSONPath 查询
$.store.book[?(@.price > 20 && @.publisher.name == 'HarperCollins' && @.reviews[?(@.rating > 4)])]
JSONPath的语法噪音比JMESPath更多一些,实际上JMESPath也更为强大一些,综合来说JMESPath还是比JSONPath是更好的选择。
结果
这些查询将返回以下匹配的书籍:
[
{
"category": "fiction",
"author": "J.R.R. Tolkien",
"title": "The Hobbit",
"price": 19.99,
"publisher": {
"name": "HarperCollins",
"location": "New York"
},
"reviews": [
{ "user": "Bob", "rating": 4 },
{ "user": "Charlie", "rating": 3 }
]
}
]
这个更复杂的查询示例涵盖了如何在不同的数据源中进行多层次、带有多个条件的查询。