过滤器选择器(上)
什么是过滤器选择器?
过滤器选择器(Filter Selector) 让你按条件筛选数据,只保留符合条件的元素。
它就像招聘时的简历筛选:"只要年龄大于 30 岁的"、"只要技术部的"。
基本语法
$[?@.age > 30] // 筛选年龄大于 30 的
$[?@.department == '技术部'] // 筛选部门是技术部的
$[?@.isActive] // 筛选 isActive 为 true 的(存在性测试)
💡 过滤器以
?开头,里面写条件表达式。@表示"当前正在检查的元素"。
存在性测试:检查字段是否存在
最简单的过滤器就是检查某个字段是否存在。如果存在,就选中这个元素。
示例
{
"members": [
{"name": "航仔", "phone": "13800138000"},
{"name": "翼王"},
{"name": "图妹", "phone": "13900139000"}
]
}
| JSONPath | 结果 | 说明 |
|---|---|---|
$.members[?@.phone] | 航仔对象、图妹对象 | 筛选有 phone 字段的 |
💡
?@.phone的意思是:"如果当前元素有phone这个字段,就选它。"翼王没有phone字段,所以被过滤掉了。
否定存在性测试
在条件前加 ! 表示"不存在":
$.members[?!@.phone]
结果:只有翼王(没有 phone 字段)。
比较表达式
过滤器支持各种比较运算符:
| 运算符 | 含义 | 示例 |
|---|---|---|
== | 等于 | @.age == 28 |
!= | 不等于 | @.department != '技术部' |
< | 小于 | @.age < 30 |
<= | 小于等于 | @.age <= 30 |
> | 大于 | @.age > 30 |
>= | 大于等于 | @.age >= 30 |
示例 JSON
{
"members": [
{"name": "航仔", "age": 28, "department": "技术部"},
{"name": "翼王", "age": 35, "department": "技术部"},
{"name": "图妹", "age": 30, "department": "产品部"},
{"name": "鸣哥", "age": 31, "department": "运营部"}
]
}
比较查询
| 查询目标 | JSONPath | 结果 |
|---|---|---|
| 年龄等于 28 | $.members[?@.age == 28] | 航仔 |
| 年龄大于 30 | $.members[?@.age > 30] | 翼王、鸣哥 |
| 年龄小于等于 30 | $.members[?@.age <= 30] | 航仔、图妹 |
| 部门是技术部 | $.members[?@.department == '技术部'] | 航仔、翼王 |
| 部门不是技术部 | $.members[?@.department != '技术部'] | 图妹、鸣哥 |
比较中的类型问题
数字 vs 字符串
{
"data": [
{"value": 13},
{"value": "13"}
]
}
| JSONPath | 结果 | 说明 |
|---|---|---|
$.data[?@.value == 13] | {"value": 13} | 数字 13 等于数字 13 |
$.data[?@.value == '13'] | {"value": "13"} | 字符串 "13" 等于字符串 "13" |
$.data[?@.value == 13] | 不会匹配 {"value":"13"} | 数字和字符串不相等! |
⚠️ JSONPath 比较时,类型必须匹配!数字
13和字符串"13"不相等。
null 的比较
{
"items": [
{"name": "航仔", "endDate": null},
{"name": "翼王"}
]
}
| JSONPath | 结果 | 说明 |
|---|---|---|
$.items[?@.endDate == null] | 航仔 | endDate 是 null |
$.items[?!@.endDate] | 翼王 | 没有 endDate 字段 |
💡
== null检查值是否为 null,!@.endDate检查字段是否存在。两者不同!
实战:飞翔科技员工筛选
示例 JSON
{
"employees": [
{"name": "航仔", "age": 28, "department": "技术部", "isActive": true},
{"name": "翼王", "age": 35, "department": "技术部", "isActive": true},
{"name": "凌叔", "age": 32, "department": "技术部", "isActive": true},
{"name": "空少", "age": 26, "department": "技术部", "isActive": true},
{"name": "风速", "age": 29, "department": "技术部", "isActive": false},
{"name": "图妹", "age": 30, "department": "产品部", "isActive": true},
{"name": "星宇", "age": 24, "department": "产品部", "isActive": true},
{"name": "靓晴", "age": 27, "department": "产品部", "isActive": true},
{"name": "鸣哥", "age": 31, "department": "运营部", "isActive": true},
{"name": "雁姐", "age": 33, "department": "运营部", "isActive": true},
{"name": "波比", "age": 25, "department": "运营部", "isActive": true},
{"name": "云吞", "age": 24, "department": "运营部", "isActive": true}
]
}
查询练习
| 查询目标 | JSONPath | 结果 |
|---|---|---|
| 年龄大于 30 | $.employees[?@.age > 30] | 翼王、凌叔、鸣哥、雁姐 |
| 年龄小于 26 | $.employees[?@.age < 26] | 星宇、云吞 |
| 技术部员工 | $.employees[?@.department == '技术部'] | 航仔、翼王、凌叔、空少、风速 |
| 已离职员工 | $.employees[?@.isActive == false] | 风速 |
| 有年龄字段的 | $.employees[?@.age] | 全部(都有 age) |
| 年龄 30 岁 | $.employees[?@.age == 30] | 图妹 |
常见错误
| 错误写法 | 问题 | 正确写法 |
|---|---|---|
$.members[@.age > 30] | 缺少 ? | $.members[?@.age > 30] |
$.members[?age > 30] | 缺少 @ | $.members[?@.age > 30] |
$.members[?@.age > 30].name ❌ | 标准语法不支持直接链式 | 视实现而定 |
$.members[?@.age = 30] | 用了单等号 | $.members[?@.age == 30] |
一句话总结
提示
过滤器 ? 按条件筛选。?@.field 检查字段存在,?@.field == value 比较值。类型必须匹配,数字和字符串不相等。条件前加 ! 表示否定!