ES查询中,有时候我们需要按照字段的长度过滤。以下为方法:
查询 name=tom且为sex=男的的员工,过滤resume个人简历描述大于50字长的
GET /user/_search
{
"query": {
"bool": {
"must":[
{"match":{"name":"tom"}},
{"match":{"sex":"男"}}
],
"filter": {
"script" : {
"script" :{
"source" : "doc['resume'][0].length()>50",
"lang" : "painless"
}
}
}
}
}
}
版本2 多个参数的传递
GET /user/_search
{
"query": {
"bool": {
"must":[
{"match":{"name":"tom"}},
{"match":{"sex":"男"}}
],
"filter": {
"script" : {
"script" :{
"params": { "markup": 50 },
"source" : "doc['resume'][0].length()>params.markup",
"lang" : "painless"
}
}
}
}
}
}
java api操作
@ResponseBody
@RequestMapping("filterResume.json")
public Map filterContext(ModelMap model, HttpServletRequest request, String begin, String end) {
Map<String, Object> bucketsPathsMap = new HashMap<>();
bucketsPathsMap.put("markup",50);
String inlineScript = "doc['resume'][0].length()>params.markup";
Script script = new Script(ScriptType.INLINE,"painless",inlineScript , bucketsPathsMap);
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("name","tom"))
.must(QueryBuilders.termQuery("sex", "男"))
.mustNot(QueryBuilders.termsQuery("address", "湖北","湖南"))
.filter(QueryBuilders.scriptQuery(script));
EstSql estSql = new EstSql(client).appendSubSql(boolQuery);
estSql.setIndexName(Constants.USER);
JSONObject result = JSONObject.parseObject(estSql.doSearch().toString());
List<JSONObject> list = result.getJSONObject("hits").getJSONArray("hits")
.stream().map(hit -> ((JSONObject) hit)
.getJSONObject("_source"))
.collect(Collectors.toList());
return ResultMap.buildMapWithData(list);
}
参数定义参见:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-expression.html