查询表达式转变为elasticsearch查询语句

来源:互联网 发布:java 前台提交post请求 编辑:程序博客网 时间:2024/06/04 18:30

查询表达式转变为elasticsearch查询语句

查询表达式:(a=1 | (b<2  | c>3 &f>6)) & (d=4  | e<5) | m >9   注意:带括号,且为多层嵌套;且不考虑&|优先级

思路:

1.切割查询表达式,使成为含有表达式,左右括号,关系& | 的  list 集合

2.遍历 list 集合。关系&|符号入符号栈;左括号、表达式入bool栈。遇到右括号时,则逆序遍历bool栈,并把遍历到的元素放入临时list中,直到遇到左括号为止。然后出栈,并处理这个临时list,并把返回的结果继续压入bool栈。循环处理,直到list无元素。

3.处理临时list。

3.1若只有一个元素,则变为DSL语句后,符号出栈;

3.2若为两个元素,则用符号栈的第一个元素,拼接为bool语句,符号出栈(只出一次);

3.3若为多个元素,则每个元素拼接为bool语句时,用栈中第一个元素,每个元素用完后符号栈出栈。最后那个元素无符号,则用最后一个出栈符号。

总结:

1.其实也不算非常复杂,但处理这个问题确实花费了很长时间。关键是基础薄弱,思路不清。一开始自己也没想好怎么做,就乱写。自己都没想好乱写的逻辑还奢望计算机能理解并正确运行。真是惭愧。最后自己思路清晰了,还真得就正确了。

2.对栈理解不深刻,用法也不熟悉。需要加强。

3.对经典问题算术表达式的处理不理解。需要熟悉。

4.写的看的代码太少。何谓见多识广,游刃有余?

import java.util.ArrayList;import java.util.LinkedList;import java.util.List;import org.elasticsearch.index.query.BoolQueryBuilder;import org.elasticsearch.index.query.QueryBuilder;import org.elasticsearch.index.query.QueryBuilders;import org.elasticsearch.index.query.QueryStringQueryBuilder;public class Test4 {public static void main(String[] args) {String s = "(a=1 | (b<2  | c>3 &f>6)) & (d=4  | e<5) | m >9";// 分割成对象,如果遇到左括号或者是|开始分割//s = "(a=1 | (b<2  | c>3 &f>6)) & (d=4  | e<5) & m >9";// //s = "(a=1 | (b<2  | c>3 &f>6 | e^3) | (d=4  & e<5) & m >9)";// //s = "a=1 | (b<2  | c>3 &f>6 | e^3) | (d=4  | e<5) & m >9";// //s = "a=1 & (b<2  | c>3 &f>6) | ((d=4  & e<5) | m >9)";// List list = getSplit(s);BoolQueryBuilder bool = doBra(list);System.out.println(bool.toString());}private static BoolQueryBuilder doBra(List listO) {LinkedList<String> opraStack = new LinkedList<String>();LinkedList boolStack = new LinkedList();Object obj;String s;List list;for (int i = 0; i < listO.size(); i++) {obj = listO.get(i);if (obj instanceof String) {s = (String) obj;if (s.equals("&") || s.equals("|")) {// 符号入栈opraStack.push(s);} else if (s.equals(")")) {// 如果碰到右括号int n = 0;list = new ArrayList<String>();int f = 0;for (int j = 0; j < boolStack.size(); j++) {// 循环以前的栈,直到左括号为止,并把未遇到左括号之前的都加入一个list中。Object obj2 = boolStack.get(j);if (obj2 instanceof String) {if (obj2.toString().equals("(")) {boolStack.pop();break;}} n++;list.add(obj2);}for (int m = 0; m < n; m++) {// 清理栈boolStack.pop();} boolStack.push(doBool(list, opraStack));// 运算后把左括号的内容加入到bool栈中} else {boolStack.push(obj);}} else {boolStack.push(obj);}}BoolQueryBuilder bool3 = doBool(boolStack, opraStack);return bool3;}private static BoolQueryBuilder doBool(List list,LinkedList<String> opraStack) {BoolQueryBuilder bool = QueryBuilders.boolQuery();String temp = null;int n = 1;boolean flag = false;for (int i = 0; i < list.size(); i++) {Object obj = list.get(i);if(list.size() == 1 || list.size()==2){if (obj instanceof Expression)obj = doCon((Expression) obj);if(opraStack.size()==0)return (BoolQueryBuilder) obj;bool = doRela(bool, (QueryBuilder) obj,opraStack.getFirst());if (i == 1)opraStack.pop();} else {if(opraStack.size()==0){flag = true;opraStack.push(temp);}if (obj instanceof Expression) {bool = doRela(bool, doCon((Expression) obj),opraStack.getFirst());} else if (obj instanceof BoolQueryBuilder) {bool = doRela(bool, (BoolQueryBuilder) obj,opraStack.getFirst());temp = opraStack.getFirst();}if (n < list.size()) {opraStack.pop();n++;}}}if(flag)opraStack.pop();return bool;}private static QueryBuilder doCon(Expression exp) {QueryBuilder qb = null;String field = exp.getValueA();String value = exp.getValueB();String con = exp.getCal();if ("=".equals(con))qb = QueryBuilders.termQuery(field, value);    else if (">".equals(con))qb = QueryBuilders.rangeQuery(field).gt(value);else if ("<".equals(con))qb = QueryBuilders.rangeQuery(field).lt(value);else if ("^".equals(con))//代替不等于qb = QueryBuilders.boolQuery().mustNot(QueryBuilders.termQuery(field, value));return qb;}private static BoolQueryBuilder doRela(BoolQueryBuilder bool,QueryBuilder subBool, String opra) {if ("&".equals(opra)) {bool.must(subBool);} else if ("|".equals(opra)) {bool.should(subBool);}return bool;}private static List getSplit(String s) {String[] ss = s.replace(" ", "").split("");List list = new ArrayList();List<String> listExp = new ArrayList<String>();for (int i = 1; i < ss.length; i++) {if (ss[i].equals("&") || (ss[i]).equals("|")) {if (listExp.size() > 0) {doList(list, listExp);}list.add(ss[i]);} else if (ss[i].equals(")") || ss[i].equals("(")) {//if (ss[i].equals(")") && listExp.size() > 0) {doList(list, listExp);}list.add(ss[i]);} else {listExp.add(ss[i]);}}if (listExp.size() > 0) {doList(list, listExp);}return list;}private static void doList(List list, List<String> listExp) {list.add(new Expression(listExp.get(0), listExp.get(2), listExp.get(1)));listExp.clear();}}



表达式实体类:

public class Expression {String valueA;String valueB;String cal;public String getValueA() {return valueA;}public void setValueA(String valueA) {this.valueA = valueA;}public String getValueB() {return valueB;}public void setValueB(String valueB) {this.valueB = valueB;}public String getCal() {return cal;}public void setCal(String cal) {this.cal = cal;}public Expression() {super();}public Expression(String valueA, String valueB, String cal) {super();this.valueA = valueA;this.valueB = valueB;this.cal = cal;}}