OpenRefine中如何提取并筛选Sherpa Romeo返回的大体积JSON的permitted_oa数组?
提取失败核心原因排查
- 路径层级不匹配:你当前使用的
value.parseJson().items.permitted_oa表达式存在两个典型错误:- Sherpa Romeo接口返回的
items是出版社条目组成的数组,数组类型无法直接通过点语法取子属性,必须通过索引或遍历逻辑访问内部元素 permitted_oa字段并非直接挂在items的子节点下,实际结构是每个item条目下的publisher_policy子节点才挂载permitted_oa数组,中间缺失了一层路径
- Sherpa Romeo接口返回的
- 类型判断偏差:你需要的5个开放获取类型字段,是
permitted_oa数组内每个对象的布尔值属性,不是数组下的顶级键,直接取数组节点自然无法匹配到目标值。
分步提取操作流程
- 第一步做结构无样本探查:不需要导出大体积JSON样例,随机选取1条完整的API返回单元格,依次执行两个短表达式定位层级:
- 执行
value.parseJson().keys()获取根节点下所有键名,确认根级items字段存在 - 执行
value.parseJson().items[0].keys()获取单个出版社条目的所有键名,确认条目中publisher_policy节点的存在,再通过value.parseJson().items[0].publisher_policy.keys()定位到permitted_oa的准确位置
- 执行
- 第二步改写数组遍历提取逻辑:针对数组类型的节点,放弃直接点取值的写法,用GREL内置的
forEach遍历所有条目做提取,通用表达式模板为:
该表达式会自动遍历所有出版社条目,把分散的forEach(value.parseJson().items, entry, entry.publisher_policy.permitted_oa).flatten()permitted_oa数组元素拍平为可处理的列表,不会因为数组类型返回空值。 - 第三步做目标字段匹配筛选:在提取到
permitted_oa列表的基础上,遍历每个政策条目,匹配指定的5个开放获取类型字段,最终提取有效结果的完整表达式为:
该逻辑会自动跳过不包含目标字段的政策节点,仅把值为true的目标开放获取类型输出,不会因为JSON体积过大出现解析失效。forEach(value.parseJson().items, entry, forEach(entry.publisher_policy.permitted_oa, policyNode, filter(['any_website','any_repository','institutional_repository','non_commercial_institutional_repository','non_commercial_repository'], fieldName, policyNode[fieldName] == true ) ) ).flatten().uniques()
大体积JSON的处理优化技巧
- 拆分存储降低单格解析压力:如果单条API返回的JSON超过1MB,不要把全量响应存在单个单元格中,提前在导入阶段按出版社条目拆分,每个单元格仅存储单个出版社的完整政策JSON,避免OpenRefine内存不足导致解析超时。
- 分面快速过滤冗余条目:将提取后的目标结果列做文本分面,一键过滤掉没有匹配到目标开放获取类型的空值条目,减少手动检查的工作量。
- 调试缩圈提升效率:测试GREL表达式时仅选中1-2行样本做验证,不要在全量数据集上直接运行长表达式,减少调试等待时间。
内容的提问来源于stack exchange,提问作者fionaglasgow
相关产品推荐
相关产品推荐

