关于查询条件交叉影响的思考
问题描述
列表查询是很常用的功能,通常有多个输入框来输入条件查询列表数据。输入框是’AND’的关系。虽然实现通常来讲很简单,但是也有一些复杂场景实现好起来是很复杂的,下面就是一个示例:
有个需求是关于设计师设计任务列表的查询功能,其中有两个搜索条件,一个是处理人(登记人、设计人、摄影人、建模人,是一个下拉框,选中一个类型再输入昵称),一个是处理时间(处理时间没有下拉框,就一个日期输入窗口),输入后查询有以下几个场景:
- 不输入处理人只输入处理时间,设计时间和摄影时间及建模时间是或的关系,也就是只要有一个对的上就算是匹配了该条数据
- 输入处理人不输入处理时间,匹配对应处理人(登记人、设计人、摄影人、建模人)的数据
- 问题在于,当既输入处理人又输入处理时间的时候:
- 如果选的是登记人,只匹配登记人,时间不产生作用
- 如果选的是设计人,既匹配设计人,又要匹配设计人的处理时间
- 如果选的是摄影人,既匹配摄影人,又要匹配摄影人的处理时间
- 如果选的是建模人,既匹配建模人,又要匹配建模人的处理时间
所有的情况穷举完了。按照需求,后端实现是很复杂的,sql执行前要根据参数类型和是否有值做大量的判断,然后根据判断结果拼接不同的查询逻辑。当然实现肯定是没问题的,但是后端同时都不认同这么做。
新的方案
后面一起讨论后的解决方案是:细化处理时间的输入条件,也就是处理时间也弄成下拉框,分别是设计师处理时间,摄影师处理时间,建模师处理时间,登记人没有处理时间。用户选则的是哪个时间输入窗口,就对应匹配哪个时间,时间是区分类型细化到不同人的。这样查询就变得很直观,所查即所得。
新的问题
这样会不会存在新的问题,把复杂性转移给了用户。当用户选择了设计人,并且选择了摄影人处理时间,是查不出结果的,类似其他的场景也是一样。我的理解是,如果抛开实现方式不谈,需求是没有问题的,站在用户的角度来讲,输入不同的角色,然后再输入时间,最好就能得到对应的数据,我哪管你时间跟觉得对应关系呢?
思考
这里存在一个复杂性谁来消耗的问题?
最开始,复杂性是后端来处理的,这真的有什么问题吗,处理实现起来相对麻烦点,在xml中有大量的逻辑判断(我们当前的实现方式,习惯在xml的test标签中来处理参数),后期也不好维护,从后端开发者的角度来讲肯定是要pass掉这种方案
问了下chat-gpt,它的建议是前端动态绑定参数来实现,也就是还是细化时间参数的方案,只不过在页面不体现出来,通过选择不同的角色来绑定不同的时间参数。我觉得这个很好了,不过如果站在前端角度来讲,这等于说是把复杂性转移给了前端,chat-gpt的建议如下:
问题分析
当前问题的复杂性来源
- 条件的组合多样性:
- 处理人和处理时间两类条件之间的逻辑关系较复杂,尤其在既输入处理人又输入处理时间的情况下,不同处理人的匹配逻辑不一致。
- 用户选择设计人处理时间时,其查询逻辑与摄影人、建模人等有所区别。
- 查询逻辑的隐性不一致:
- 当用户选择设计人,却选了摄影人处理时间,出现“查不到数据”的结果。从技术上来说符合逻辑,但从用户体验的角度来看,可能引起困惑。
- 需求变化后的逻辑清晰度提升:
- 通过将处理时间细化为多个输入条件(例如设计人处理时间、摄影人处理时间等),逻辑变得更直观,但这种设计也将部分输入责任转移给了用户(例如处理人和处理时间的匹配需要用户自己意识到)。
现有方案的优点
- 查询直观:
- 通过细化处理时间的选择,查询条件明确,所查即所得,减少了逻辑复杂度。
- 用户对条件的输入更明确,查询过程符合“用户输入->匹配结果”的直觉。
- 逻辑清晰:
- 后端查询逻辑简化,不需要再处理复杂的“处理人+处理时间”的组合匹配问题。
- 结果符合逻辑:
- 如果条件冲突(如选择设计人+摄影人处理时间),查询不到结果是合理的,符合设计意图。
潜在问题
- 用户体验问题:
- 对普通用户来说,条件细化后的逻辑可能不够直观,例如他们可能没有意识到选择“设计人+摄影人处理时间”会导致查询无结果。
- 如果用户输入了一个“矛盾”的条件组合,界面未明确提示,可能会让用户产生困惑。
- 复杂性转移:
- 细化输入条件虽然简化了代码实现,但将复杂性转移到了用户端,用户需要对条件组合关系有较清楚的理解。
- 某些情况下,用户可能需要重复尝试不同组合才能找到他们需要的结果。
改进建议
1. 增强用户体验的引导
(1)条件依赖动态变化
当用户选择某个处理人(例如设计人)时,只显示与之匹配的处理时间输入窗口(即仅展示“设计人处理时间”)。
如果选择“登记人”,隐藏所有时间输入框,因为登记人没有处理时间的概念。
实现方式
:
- 前端动态绑定条件显示逻辑。
- 用户选择处理人后,后台返回与之相关的时间条件。
(2)条件冲突提示
- 如果用户选择了互斥条件(如设计人+摄影人处理时间),在查询前即时提示:“处理时间与处理人不匹配,请调整条件”。
- 提示内容可以用高亮文字显示在页面上,或以弹窗形式提醒。
2. 提供默认的“宽松查询”模式
为避免用户因条件不匹配而查不到结果,可以提供一种宽松查询模式,调整查询逻辑:
- 规则:
- 如果用户输入设计人,但选择了摄影人处理时间,则放宽匹配条件:
- 匹配设计人。
- 或匹配摄影人处理时间。
- 提示用户这是宽松查询结果(例如在结果列表顶部显示“部分条件未完全匹配”)。
- 实现:
- 在 SQL 或查询逻辑中,增加“或”逻辑,默认情况下允许匹配部分条件。
3. 增加筛选条件的清晰度
通过界面设计增加筛选条件的可理解性,减少用户困惑:
改进处理时间选择框的标签
:
- 将“摄影人处理时间”改为更明确的描述,例如“仅限摄影人数据的处理时间”。
- 增加说明文字:提示“处理人和处理时间需保持一致”。
添加智能搜索提示
:
- 当用户输入不合理组合时,弹出可能的修正建议。例如“您选择了设计人,但输入了摄影人处理时间,是否改为选择摄影人?”
4. 优化代码逻辑(查询逻辑)
优化查询逻辑,使其支持上述功能:
动态条件拼接
:
- 使用
SQL
动态拼接条件,确保处理人和时间条件相互匹配。条件优先级处理
:
- 按条件的重要性排列优先级。例如:
- 优先匹配处理人。
- 如果处理人为空,则匹配处理时间的“或”条件。
总结
你的方案通过细化条件设计,大大简化了查询逻辑,这是非常好的思路。但可以进一步增强用户体验,引导用户输入正确条件,减少困惑。结合动态条件显示和冲突提示等方法,既能保持代码简洁,又能提升用户满意度。
此外,在代码层面,确保查询逻辑的灵活性和条件的动态组合处理,可以更好地满足未来可能的扩展需求。
再问问chat-gpt,这样就把复杂性转移给了前端,它是这样回答的:
前端复杂性转移的利与弊
优点
- 用户输入直观清晰
- 用户通过可视化界面理解查询条件,不需要推测后端的处理逻辑。
- 动态交互(如根据处理人显示对应的处理时间)减少了用户的错误输入。
- 后端代码逻辑简化
- 将条件的动态处理前置到前端,后端只需处理明确的输入,避免了复杂的条件组合查询逻辑。
- 提高响应速度
- 动态的前端逻辑减少了无效查询(如用户输入不合理组合条件),避免后端资源浪费。
缺点
- 前端逻辑复杂化
- 前端需要动态管理条件的显示和冲突检测,可能增加代码复杂性。
- 如果后续查询条件需要调整,前端也需要同步更新,增加了维护成本。
- 用户体验依赖前端实现
- 如果前端设计不够直观或提示不到位,用户可能仍会输入错误组合,导致不符合预期的查询结果。
- 责任边界不清
- 一些逻辑本应由后端处理(如条件优先级判断),却放到前端,这可能导致系统维护复杂化。
优化平衡前后端职责的建议
1. 将复杂性适当分担
动态条件显示仍由前端负责
:
- 这是用户体验的核心功能,处理人和处理时间的动态联动是前端擅长的领域。
- 前端负责基础的输入验证和条件关系的动态更新。
条件冲突提示由后端提供
:
- 前端只负责收集用户输入的条件,后端在查询逻辑中判断条件是否冲突,并返回提示信息。
- 例如,用户提交查询后,后端返回“处理人和处理时间不匹配”的提示,前端只需显示这条信息。
2. 使用统一的查询规则
查询逻辑集中在后端
:
- 后端维护一套核心的条件处理逻辑,前端只负责将用户输入的内容格式化发送给后端。
规则更新统一管理
:
- 如果后续业务逻辑变化(如新增处理人类型或时间条件),只需要更新后端逻辑,而前端无需复杂调整。
3. 智能化查询功能
- 在用户提交查询前,前端通过调用后端接口,预先检查条件是否合法:
- 如果条件冲突,直接提示用户调整。
- 如果条件组合不完整,提供默认或宽松查询模式。
4. 降低前端复杂性
- 使用现有框架或工具简化动态交互逻辑:
- 前端可使用状态管理库(如 Vuex、Redux)或条件绑定工具(如 Vue 的
v-if
和 React 的条件渲染)来动态管理条件展示。- 通过清晰的数据结构,将条件关系解耦,减少前端代码混乱。
总结
复杂问题通过具体细化后,是能变得很简单很清晰的,这样就不是什么问题
当然具体细化这个动作,是有一定复杂性的,这个转移给回来处理,值得商榷
当前我们还是选择了将复杂性转移给了用户,毕竟这是内部的工具,使用体验也没有那么差吧