如何可靠解析org.apache.lucene.search.BooleanQuery的toString()输出?
可靠解析Lucene BooleanQuery的toString()输出方案
BooleanQuery的toString()方法本质是调试用的人类可读输出,并非为机器解析设计,所以直接用SimpleQueryParser解析肯定会踩坑——比如你遇到的#字符,它是Lucene内部用来标记特定查询类型(比如SpanQuery或嵌套布尔查询)的符号,不属于标准查询语法,自然会被Analyzer过滤或解析器忽略。
给你几个靠谱的解决思路:
彻底抛弃用toString()做解析的思路:
这是最根本的解决方案。如果需要持久化、传递Query对象,要么直接序列化Query实例(比如用Java原生序列化、Kryo等序列化框架),要么在生成Query时就同步生成符合Lucene标准查询语法的字符串(而不是依赖toString()输出)。比如你的示例查询,标准语法应该写成:+(title:bi OR title:"business intelligence")这个字符串用SimpleQueryParser可以直接正确解析。
若必须处理toString()输出,手动适配格式:
如果只能拿到toString()的输出,需要先做格式转换:- 识别并替换内部标记:比如把
#(...)直接替换成(...),因为这里的#只是内部标记,实际对应的是嵌套的布尔查询。 - 补全逻辑操作符:Lucene的toString()会省略默认的OR操作符,所以要把
title:bi title:"business intelligence"补全为title:bi OR title:"business intelligence"。 - 注意:这种方法需要你对Lucene各类Query的toString()格式非常熟悉,不同Query类型的输出标记不同,后续Lucene版本更新可能还会变化,维护成本高,仅作为临时方案使用。
- 识别并替换内部标记:比如把
自定义解析器适配toString()格式:
如果你经常需要处理这种场景,可以基于Antlr或手写解析逻辑,专门针对Lucene Query的toString()格式做解析,将其转换为对应的Query对象。但同样,这种方案需要跟随Lucene版本做适配,性价比不高。
内容的提问来源于stack exchange,提问作者Carl Mastrangelo
相关产品推荐
相关产品推荐

