云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

分布式存储_最便宜服务器_怎么申请

小七 141 0

使用JMESPath为用户提供JSON查询

博客开发分析应用程序是产品团队一个大胆的新方向。工具箱是我们讨论开发最佳实践、技巧、技巧和成功案例的地方,帮助您构建分析的未来,并为您的用户提供所需的见解和行动。JSON可能是当今开放数据交换中最常见的格式。尽管JSON文档被设计成一种类似JavaScript对象的轻量级格式,但它可以变得非常大,特别是当它们包含深度嵌套的对象和数组时确实需要能够对JSON文档运行常规处理查询,以过滤、整形和转换JSON数据一些文档数据库(如MongoDB和PostgreSQL)有自己的查询语言,允许在JSON上运行复杂的查询,但是当JSON数据在数据库记录的上下文之外时,这通常是无关紧要的(尽管您可以使用MingoJS,MongoDB查询语言的JavaScript实现)。如果我们可以为用户提供对此类查询的内置支持呢? 用例:您的软件输出一些JSON,您希望为用户提供一种简单、标准化的方法来过滤或操作数据(例如:api、sdk、CLIs、在线游戏场)。您的软件将JSON作为输入,您希望以一种统一且可重用的方式以编程方式过滤或操作数据。(想想JSON文档中的对象数组嵌套了更多的数组和对象)是的,您可以使用map、filter和reduce函数编写自己的逻辑,但也许还有更好的、更具声明性的方法。这篇文章主要集中在第一个用例上,你想给你的用户一个内置的选项来处理输出(但事实上,这两个用例是相似的)。JSON查询语言的候选项XML具有用于查询和遍历XML节点的XPath。JSON的等价物是什么? JSONPath公司JSONPath - "XPath for JSON" - 是第一个想到的查询语言。它是JSON查询语言最早的实现之一,它完成了任务。它的一个优点是它允许遍历整个JSON树(例如访问父节点),并且可以将树中的路径位置作为JSON指针(键)输出问题是,如果我们希望向用户提供基于JSONPath的接口,那么JSONPath的语法不是很直观。然而,更大的问题是它没有严格的规范,这意味着有很多JSONPath的实现可能会产生不同的结果。这使得在许多场景中很难依赖JSONPathjq公司jq是使用强大的JSON查询语言的命令行JSON处理器。你几乎可以用jq做任何事情!这种通用语言在DevOps中很流行,可能是因为它的CLI使得通过管道传输另一个进程的输出变得容易,然后使用jq的管道系统通过其他管道处理格式化的输出但有两个问题:jq是一个命令行工具,而不是我们可以用自己的api、sdk等向用户提供的接口。jq和jq库可能会因为jq和jq的实时性能而受到影响。第二,强大的功能带来了极大的复杂性,一些用户声称jq是一种过于复杂的语言,对于我们的用例来说,jq可能是一种过火的语言,因为它允许的不仅仅是操作现有的JSON杰梅斯帕JMESPath是一种JSON查询语言,允许对JSON文档进行复杂的过滤、提取和转换。与JSONPath和jq不同,它有一个完整的规范和精确的语法,因此语法在所有实现中都定义得很好。它有许多语言(Java、Python、JavaScript、Go、PHP等)完全兼容的库。它是一种功能强大的查询语言,但语法非常简单出于这些原因,当涉及到将JMESPath作为面向用户的界面集成到我们自己的服务中时,JMESPath是我们的首选语言。它有一个友好的操场和教程,我们可以提供给用户作为参考。关于jmespath.org/examples.html可以让您了解该语言的强大和简单性用户的权力多亏了库,将JMESPath添加到我们的服务代码中非常简单。通过集成JMESPath,我们现在可以为我们的API、SDK或CLI用户提供一个强大、简单、标准化的方法来塑造从我们的服务返回的JSON响应,而不需要外部工具。例如,我们假设我们的服务是一个公共restapi。通过给用户指定对数据的JMESPath查询的能力,用户最终可以节省时间、线路上的字节和进行后处理的代码行,因为处理发生在服务器上,响应正好包含用户需要的内容。在API处理程序代码中集成JMESPath非常简单,因为库只有一个函数("search")。这里,作为节点.js/JavaScript代码:const jmespath=需要('jmespath');const requestHandler=(req,res,next)=>{//响应res是从上一个处理程序传递到这里的如果(需求查询&& 请求查询过滤器) {res=应用JMespathFilter(res,请求查询过滤器);}//…更多的逻辑,最终回复发送()}const applyJmesPathFilter=(res,jmespathExpression)=>{试试看{资源=jmespath.search(res,jmespathExpression)| |{};}接球(e){res={};日志.错误(e) ;}返回res;}这样,用户可以立即使用filter query参数指定一个JMESPath表达式来处理初始JSON结果:GET/api/玩家?筛选器=[JMESPATH_表达式]假设我们的服务的输出是NBA players API,其中有一些传奇篮球运动员的信息。GET/api/players请求返回以下JSON对象数组:[{"playerId":"7c3f73dd-0b38-48dc-9347-c78811bd80c4","斯考特彭":"斯考特彭","出生年份":"1965","collegeId":"77302082-2758-48cc-ab3a-7b811a8bdf80","jerseyNumber":"33","玩家状态":{"点数":18940,"篮板":7494,"助攻":6135},"团队名称":["芝加哥公牛队","波特兰开拓者","休斯顿火箭队","芝加哥公牛队"]},{"playerId":"8d75bb0f-a444-4264-a583-4ca5799169cf","playerName":"帕特里克·尤因","出生年份":"1962","collegeId":"0456a17b-320d-4ddc-bfc2-011670af2b77","jerseyNumber":"33","玩家状态":{"点数":24815,"篮板":11617,"方块":2894},"团队名称":["纽约尼克斯","西雅图超音速","奥兰多魔术"]}]由于原始结果是一个数组,下面的JMESPath表达式以"[]"开头来引用该数组。GET/api/玩家?filter=[]。playerName将返回以下数组:["苏格兰皮蓬","帕特里克·尤因"]我们还可以请求对象,并修改原始密钥名:GET/api/玩家?filter=[]。{name:playerName,number:jerseyNumber}返回:[{"name":"斯科蒂·皮蓬","数字":"33"},{"name":"帕特里克·尤因","数字":"33"}]我们可以基于一个或多个键运行过滤器查询,并通过管道将结果格式化(此处为纯字符串):GET/api/玩家?过滤器=[?yearOfBirth>`1964`].playerName |[0]返回:"斯科蒂·皮蓬"以及更高级的逻辑,它使用sort()和join()函数:GET/api/玩家?filter=[].playerName |排序(@){nbaLegends:join(',',@)}{"nbaLegends":"帕特里克·尤因,斯科蒂·皮蓬"}用户可以对结果进行调整,以便根据他们的具体需要进行调整。例如:GET/api/玩家?filter=[]。{name:playerName,firstTeam:teamNames |[0],点数:玩家状态点}[{"name":"斯科蒂·皮蓬","firstTeam":"芝加哥公牛队","点数":18940},{"name":"帕特里克·尤因","firstTeam":"纽约尼克斯","点数":24815}]这些只是JMESPath提供的一些JSON处理选项一些读者可能会注意到,使用GraphQL可以让用户"准确地获得他们想要的数据"。是的,但是这个特定的选项描述了一个restapi(场景可以被SDK或CLI代替)。事实上,GraphQL并没有提供JMESPath之类的JSON查询语言所提供的处理能力。当然,JSON处理在完全获取初始数据集之后运行,这不如在数据访问层上使用解析器(如graphqlapi)进行早期过滤那样高效我已经将JMESPath集成到一些Sisense公共restapi中,并作为GraphQL2REST包中的一个特性。局限性与jq和JSONPath相比,JMESPath有一些局限性。对我来说,最大的限制是没有简单的方法来获取给定JSON文档的路径列表(也称为节点名或JSON指针),并且不能将键表示为JMESPath表达式(以便在满足测试的一组键上运行操作)。递归遍历是不可能的 - 您必须指定JSON键的完整路径。另一个问题是JMESPath不允许在迭代时引用父节点。这些限制有时会限制开发人员的使用,但通常不会影响这里讨论的常见用例。额外资源对于冒险家 - 更多查询语言:YAQL(又一种查询语言)rq Query languagejl(JSON lambda)Query languageglom(Python)object path(JavaScript)jp:JMESPath的命令行接口(CLI)Sisroy s研发团队的负责人。在Sisense工作之前,他曾在初创公司、微软和英特尔担任全套开发人员,并担任独立顾问。他有超过15年的软件编写经验。标记:数据模型API | json