需求回顾
1、业务需要根据ES内部多个字段进行比较运算
2、不能使用外部参数进行传入比较
技术回顾
1、script参数能够自由定义需要比较运算的字段
2、script参数能够适用各种业务场景,一般restApi实现不了的都能够解决
小试牛刀
本文直接适用java语言进行演示
本次测试查询 【年龄 -10 > 工龄 * 2 】的数据
1、定义项目pom以及application
1.1 pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
1.2 application.yml
spring:
elasticsearch:
username: elastic
password: VaHcSC3mOFfovLWTqW6E
uris: 10.10.22.174:9200
connection-timeout: 1s
socket-timeout: 30s
2、创建es 索引及业务实体
2.1 es文档实体
/**
*
* 用户实体
* @author senfel
* @version 1.0
* @date 2022/7/26 10:40
*/
@Data
@Document(indexName = "users")
public class Users {
/**
* id
*/
private Long id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 工龄
*/
private Integer workAge;
}
2.2 创建es索引并增加测试数据
@Test
void contextLoads() {
//创建索引
boolean usersFlag = elasticsearchRestTemplate.indexOps(IndexCoordinates.of("users")).create();
if(usersFlag) {
//设置测试数据
for (int i = 0; i < 100; i++) {
Users users = new Users();
users.setAge(25 + i / 10 + i % 10);
users.setWorkAge(3 + i / 10 + i % 10);
users.setName("senfel" + i);
users.setId(Long.valueOf(i + ""));
Users save = elasticsearchRestTemplate.save(users);
System.err.println(save);
}
}
}
2.3 测试数据
3、组装script语句,本次测试查询 <年龄-10 > 工龄 * 2> 的数据
3.1 java查询es语句
/**
* 测试es script
* @author senfel
* @date 2022/7/26 10:48
* @return void
*/
@Test
public void testEsByScript(){
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{"id","name","age","workAge"},null)).withPageable(PageRequest.of(0,10));
//查询条件
BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
ScriptQueryBuilder builderByScript = new ScriptQueryBuilder(new Script("if (doc['age'].value -10 " +
"> doc['workAge'].value * 2){ return true}else{return false}"));
queryBuilder.must(builderByScript);
nativeSearchQueryBuilder.withQuery(queryBuilder);
String esInfo = nativeSearchQueryBuilder.build().getQuery().toString();
System.err.println(esInfo);
long count = elasticsearchRestTemplate.count(nativeSearchQueryBuilder.build(), Users.class);
if(count > 0){
SearchHits<Users> searchHits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), Users.class);
List<SearchHit<Users>> datas = searchHits.getSearchHits();
datas.forEach(
System.err::println
);
}
}
3.2 es query语句与查询结果
{
"bool" : {
"must" : [
{
"script" : {
"script" : {
"source" : "if (doc['age'].value -10 > doc['workAge'].value * 2){ return true}else{return false}",
"lang" : "painless"
},
"boost" : 1.0
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
总条数45
SearchHit{id=‘0’, score=NaN, sortValues=[0], content=Users(id=0, name=senfel0, age=25, workAge=3), highlightFields={}}
SearchHit{id=‘1’, score=NaN, sortValues=[1], content=Users(id=1, name=senfel1, age=26, workAge=4), highlightFields={}}
SearchHit{id=‘2’, score=NaN, sortValues=[2], content=Users(id=2, name=senfel2, age=27, workAge=5), highlightFields={}}
SearchHit{id=‘3’, score=NaN, sortValues=[3], content=Users(id=3, name=senfel3, age=28, workAge=6), highlightFields={}}
SearchHit{id=‘4’, score=NaN, sortValues=[4], content=Users(id=4, name=senfel4, age=29, workAge=7), highlightFields={}}
SearchHit{id=‘5’, score=NaN, sortValues=[5], content=Users(id=5, name=senfel5, age=30, workAge=8), highlightFields={}}
SearchHit{id=‘6’, score=NaN, sortValues=[6], content=Users(id=6, name=senfel6, age=31, workAge=9), highlightFields={}}
SearchHit{id=‘7’, score=NaN, sortValues=[7], content=Users(id=7, name=senfel7, age=32, workAge=10), highlightFields={}}
SearchHit{id=‘8’, score=NaN, sortValues=[8], content=Users(id=8, name=senfel8, age=33, workAge=11), highlightFields={}}
SearchHit{id=‘10’, score=NaN, sortValues=[10], content=Users(id=10, name=senfel10, age=26, workAge=4), highlightFields={}}