欢迎投稿

今日深度:

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

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


查询表达式转变为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;
	}
}


www.htsjk.Com true http://www.htsjk.com/Elasticsearch/35192.html NewsArticle 查询表达式转变为elasticsearch查询语句, 查询表达式转变为elasticsearch查询语句 查询表达式:(a=1 | (b2  | c3 f6)) (d=4  | e5) | m 9   注意:带括号,且为多层嵌套;且不考虑|优先级 思路:...
相关文章
    暂无相关文章
评论暂时关闭