当前位置: 首页 > 知识库问答 >
问题:

javascript - 怎么编写支持灵活过滤的列表接口,解析前端过滤表达式?

葛鸿熙
2023-11-10

一个列表接口需要支持灵活且复杂的过滤条件一般都是怎么实现的?

我目前的想法是,前端通过过滤组件,生成一个过滤表达式,如查询价格小于100,且列别为tools或者 toolbox 的项目,则表达式为 price <= 100 and category in ['tool', 'toolkit']

我目前使用go开发后端接口,我找到一个表达式库 https://github.com/antonmedv/expr,但是不知道该怎么将表达式转为SQL查询,数据库查询我使用的是 GORM。

这个库可以直接计算表达式的结果,但是这和我的需求不符合,我需要将表达式转为通过GORM的SQL查询,然后我尝试了通过这个库的ast 和 sqlbuilder 手动解析并转换成 SQL 查询,但是没有成功,有些复杂一点或者嵌套条件,我不知道怎么解析语法树。

有人有类似的需求么,请问都是怎么实现的?

类似的功能我在 jira 的查询中也见过,但是不知道他们是怎么实现的。

谢谢!

共有4个答案

刘承运
2023-11-10

前端先定义一个结构吧,类似:

interface Expression {  type: 'and' | 'or',  children: Array<Expression>}const res: Expression = {  type: 'and',  children: [    {      type: 'or',      children: [        { type: 'and', children: [a] }        { type: 'and', children: [b, c] }      ]    },    {      type: 'or',      children: [d, e]    }  ]}

或者这种https://segmentfault.com/q/1010000044348562/a-1020000044348815

再去解析json生成sql字符串,和解析语法树没啥关系,又不是把sql反向解析成结构体

阎晗日
2023-11-10

你换成json解析json应该问题不大吧,例如,让前端组装成这种数据结构,服务端通过解析type 组装成简单的表达式问题应该不大吧

{"a":{    "type":"eq",    "value": 1  },"b":{    "type":"in",    "value":["1","3"] },"c":{    "type":"lte",    "value": "3" }}
邰棋
2023-11-10

image.png

庞鸿骞
2023-11-10

这个问题确实比较复杂,你需要将前端的过滤表达式解析为后端可以理解的SQL查询。在这个过程中,可能需要处理的问题包括:

  1. 解析过滤表达式:你需要将前端的过滤表达式解析成一个可理解的语法树。这可能需要使用到一些语法解析库,例如Go的"parser"包或者ANTLR等。
  2. 转换为SQL查询:解析完过滤表达式后,你需要将其转换为SQL查询。在这个过程中,你可能需要使用到GORM的查询接口,以及你可能需要对SQL查询的语法有深入的了解。

在这个过程中,可能会遇到一些复杂或者嵌套的条件,这时候可能需要一些高级的解析技术,例如使用到递归下降解析等。

另外,你也可以考虑一些更高级的解决方案,例如使用一些ORM框架(例如GORM、Sequelize等)提供的查询接口,这些接口通常可以更方便的构建复杂的查询条件。

对于你提到的antonmedv/expr库,这个库主要是用于计算表达式的值,而不是生成SQL查询。因此,你可能需要寻找其他的解决方案。

如果你对这个过程还有任何疑问,或者需要更具体的代码示例,欢迎你随时提问。

 类似资料:
  • 过滤表达式 mitmproxy工具中的许多命令都使用过滤器表达式。过滤器表达式由以下运算符组成: 命令 描述 〜a 匹配响应资源:CSS,Javascript,Flash,images。 〜b regex Body 〜bq regex 请求的Body 〜bs regex 响应的Body 〜c int HTTP响应码 〜d regex 域名 〜dst regex 匹配目标地址 〜e 匹配错误 〜h

  • 问题内容: 我开始使用django-tables2(从第一印象中就可以强烈推荐),我问自己如何实现列过滤。我找不到合适的文档,但是我确定它在那里。 问题答案: 答案有点晚了,但是无论如何…我也找不到任何合适的文档来进行列过滤。有很多方法可以做到这一点: 答:手动:我添加了一个包含要过滤的字段的表单,然后在我的视图中执行以下操作: 这很好用,但是不是那么干,因为它在视图中是硬编码的。 B.使用Sin

  • 4.5. 过滤列表 如你所知,Python 具有通过列表解析(第 3.6 节 “映射 list”)将列表映射到其它列表的强大能力。这种能力同过滤机制结合使用,使列表中的有些元素被映射的同时跳过另外一些元素。 过滤列表语法: [mapping-expression for element in source-list if filter-expression] 这是你所知所爱的 列表解析 的扩展。

  • 问题内容: 我有一堂课: 然后,我有了另一个主要功能,其中有一个功能,必须根据年份过滤该项目列表,并获得名称列表作为结果。 您能告诉我如何使用Java 8 Lambda表达式吗? 谢谢 问题答案: 好吧,您没有说明确切的过滤条件,但是假设您希望按给定年份过滤元素:

  • 问题内容: 我在使用棘手的SQL查询时遇到了一些麻烦。 在我的MySQL数据库中,有表主题,标签和tags_topics可以将它们连接起来。我想获取共享相同指定标签的主题。例如,假设我有3个ID为1、2和3的标签,我想获取所有与标签1、2和3相关联的主题。主题可以具有其他标签,但必须具有所有指定的标签。 帮我思考一下plz xD 编辑:在以下问题中找到了使用GROUP BY的解决方案:仅获取与联接

  • 过滤字段的列表,每一个成员应该是数组或对象 $data = [ ['id'=>1, 'name'=>'a'], ['id'=>2, 'name'=>'b'], ]; // 两个毫无意义的实例化写法 $list = new FilterableList; $list = new FilterableList($data); // 只保留 name 字段 $list = new Fi