包含当前es所有的查询,
需要什么代码直接照搬,改个参数就行!
用的好请务必给我点赞!!!感谢爱你们!!!
为啥写这篇文章呢:
大概是因为目前公司用的api跟以前的不太一样,
以前我们是基于高标准客户端直接做的,
但是目前这边同事是基于elasticsearchresttemplate跟nativesearchquery做的。
import lombok.extern.slf4j.slf4j;
import org.elasticsearch.common.lucene.search.function.combinefunction;
import org.elasticsearch.index.query.boolquerybuilder;
import org.elasticsearch.index.query.matchallquerybuilder;
import org.elasticsearch.index.query.matchquerybuilder;
import org.elasticsearch.index.query.multimatchquerybuilder;
import org.elasticsearch.index.query.querybuilders;
import org.elasticsearch.index.query.rangequerybuilder;
import org.elasticsearch.index.query.termsquerybuilder;
import org.elasticsearch.index.query.wildcardquerybuilder;
import org.elasticsearch.index.query.functionscore.functionscorequerybuilder;
import org.elasticsearch.index.query.functionscore.scorefunctionbuilder;
import org.elasticsearch.index.query.functionscore.scorefunctionbuilders;
import org.elasticsearch.search.builder.searchsourcebuilder;
import org.elasticsearch.search.fetch.subphase.highlight.highlightbuilder;
import org.elasticsearch.search.sort.sortbuilder;
import org.elasticsearch.search.sort.sortbuilders;
import org.elasticsearch.search.sort.sortorder;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.data.domain.pagerequest;
import org.springframework.data.domain.pageable;
import org.springframework.data.domain.sort;
import org.springframework.data.elasticsearch.core.elasticsearchresttemplate;
import org.springframework.data.elasticsearch.core.searchhit;
import org.springframework.data.elasticsearch.core.searchhits;
import org.springframework.data.elasticsearch.core.mapping.indexcoordinates;
import org.springframework.data.elasticsearch.core.query.nativesearchquery;
import org.springframework.data.elasticsearch.core.query.nativesearchquerybuilder;
import org.springframework.web.bind.annotation.postmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
import java.util.list;
import java.util.map;
@slf4j
@restcontroller
@requestmapping("/v/k/t/query")
public class estestcontroller {
//聚合2
//参加聚合的字段必须是keyword、日期、数值、布尔类型
@postmapping("/es/agg2")
public void agg2() throws ioexception {
// 1.创建request对象
searchrequest request = new searchrequest("298_ops-web-js_1");
// 2.准备请求的参数:dsl语句
request.source().size(0);
//参数一:聚合查询的名字 参数二:根据appid做分组 参数三:最多显示10条
// termsaggregationbuilder aggregationbuilder = aggregationbuilders.max("bsversionagg").field("appid");
maxaggregationbuilder maxaggs = aggregationbuilders.max("score").field("bsversion");
request.source().aggregation(
maxaggs
);
try {
searchresponse response = client.search(request, requestoptions.default);
aggregations aggregations = response.getaggregations();
terms bsversionagg = aggregations.get("bsversionagg");
list<? extends terms.bucket> buckets = bsversionagg.getbuckets();
for (terms.bucket bucket : buckets) {
string key = bucket.getkeyasstring();
//getdoccount:该桶下的文档总数
long doccount = bucket.getdoccount();
log.info("key:{},doccount:{}", key, doccount);
}
} catch (ioexception e) {
log.error("es查询异常:{}", e.getmessage());
}
}
//聚合
//参加聚合的字段必须是keyword、日期、数值、布尔类型
@postmapping("/es/agg")
public void agg() {
// 1.创建request对象
searchrequest request = new searchrequest("298_ops-web-js_1");
// 2.准备请求的参数:dsl语句
request.source().size(0);
//参数一:聚合查询的名字 参数二:根据appid做分组 参数三:最多显示10条
termsaggregationbuilder aggregationbuilder = aggregationbuilders.terms("bsversionagg").field("appid").size(5);
request.source().aggregation(
aggregationbuilder
);
try {
searchresponse response = client.search(request, requestoptions.default);
aggregations aggregations = response.getaggregations();
terms bsversionagg = aggregations.get("bsversionagg");
list<? extends terms.bucket> buckets = bsversionagg.getbuckets();
for (terms.bucket bucket : buckets) {
string key = bucket.getkeyasstring();
//getdoccount:该桶下的文档总数
long doccount = bucket.getdoccount();
log.info("key:{},doccount:{}", key, doccount);
}
} catch (ioexception e) {
log.error("es查询异常:{}", e.getmessage());
}
}
/************************************************************************
————————————————————————————以下为不携带聚合的查询————————————————————————————————————————————
************************************************************************/
/**
* 测试es各种查询方法*
*/
@autowired
elasticsearchresttemplate elasticsearchresttemplate;
//通配符查询
@postmapping("/es/wildcard")
public void wildcard() {
//*:匹配任意数量的字符(包括零个字符)。 *x*: 对x做前后n位做模糊查询,前后有多少值都可以查到(也可以左模糊或者右模糊)
//?:用于匹配单个字符. user?a: user?a 匹配user1a,但不匹配user123a
//^:必须以某个字符开头,如^user*:必须以user开头
//$:必须以某个字符结尾,如user$:必须以user结尾
boolquerybuilder boolquerybuilder = querybuilders.boolquery();
//wildcardquery:通配符查询
wildcardquerybuilder bsversion = querybuilders.wildcardquery("bsversion", "*1*");
wildcardquerybuilder bsversion2 = querybuilders.wildcardquery("type", "*j*");
boolquerybuilder.must(bsversion).should(bsversion2);
nativesearchquery dsl = new nativesearchquerybuilder()
}
//高亮
//默认情况下:只能对查询字段高亮!!!
//加了.requirefieldmatch(false) 可以对非查询字段高亮,具体看下文
@postmapping("/es/highlight")
public void highlight() {
boolquerybuilder boolquerybuilder = querybuilders.boolquery();
//wildcardquery:通配符查询
wildcardquerybuilder bsversion = querybuilders.wildcardquery("bsversion", "*1*");
wildcardquerybuilder bsversion2 = querybuilders.wildcardquery("type", "*j*");
boolquerybuilder.must(bsversion).should(bsversion2);
nativesearchquery dsl = new nativesearchquerybuilder()
.withquery(boolquerybuilder)
.withhighlightfields(
//.requirefieldmatch(false) : 加了可以对非查询字段高亮
new highlightbuilder.field("bsversion").pretags("<em>").posttags("</em>").requirefieldmatch(false),
new highlightbuilder.field("provincenamecn").pretags("<em>").posttags("</em>").requirefieldmatch(false),
new highlightbuilder.field("isp").pretags("<em>").posttags("</em>").requirefieldmatch(false),
new highlightbuilder.field("type").pretags("<em>").posttags("</em>").requirefieldmatch(false),
new highlightbuilder.field("agentid").pretags("<em>").posttags("</em>").requirefieldmatch(false)
)
.build();
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
for (searchhit<map> searchhit : search.getsearchhits()) {
// 高亮字段是个大map 高亮字段集合 = {bsversion=[<em>115</em>]} //k=字段名 v=高亮了的数据集合
map<string, list<string>> highlightfields = searchhit.gethighlightfields();
system.out.println("获取高亮字段集合:bsversion = " + highlightfields.get("bsversion"));
system.out.println("获取高亮字段集合:provincenamecn = " + highlightfields.get("provincenamecn"));
system.out.println("获取高亮字段集合:isp = " + highlightfields.get("isp"));
system.out.println("获取高亮字段集合:type = " + highlightfields.get("type"));
system.out.println("获取高亮字段集合:agentid = " + highlightfields.get("agentid"));
list<string> bsversionresult = highlightfields.get("bsversion");
for (string s : bsversionresult) {
system.out.println("bsversion集合每一个值为 = " + s);
}
// highlightfields.foreach((k, v) -> {
// //获取高亮字段:k = bsversion v = [<em>115</em>]
// system.out.println("获取高亮字段:k = " + k + " v = " + v);
// });
}
log.info("总条数:{}", search.gettotalhits());
system.out.println("search.getsearchhits().size() = " + search.getsearchhits().size());
}
//排序
@postmapping("/es/sort")
public void sort() {
matchallquerybuilder matchallquery = querybuilders.matchallquery();
//备注:这里用的是nativesearchquerybuilder:xxxbuilder。最后一定要.build();,不然条件用不了
nativesearchquery dsl = new nativesearchquerybuilder()
.withquery(matchallquery)
//备注:应该是要keyword,paasword这一类才能排序。我用text类型排序报:非法字段异常
.withsorts(sortbuilders.fieldsort("appid").order(sortorder.asc)) //排序:根据bsversion升序排序
.build();
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
for (searchhit<map> searchhit : search.getsearchhits()) {
system.out.println("单条文档的原数据 = " + searchhit.getcontent());
system.out.println("单条文档的id = " + searchhit.getid());
system.out.println("单条文档的评分 = " + searchhit.getscore());
system.out.println("单条文档索引名(表名) = " + searchhit.getindex());//298_ops-web-js_1就是你输入的索引库名
}
}
//分页
@postmapping("/es/page")
public void page() {
integer page = 1;
integer size = 10;
matchallquerybuilder matchallquery = querybuilders.matchallquery();
nativesearchquery dsl = new nativesearchquery(matchallquery);
//分页
pageable pageable = pagerequest.of((page - 1) * size, size);
dsl.setpageable(pageable);
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
// 获取当前页数
log.info("当前页数:{}", page);
// 获取当前页的条数
int currentsize = search.getsearchhits().size();
log.info("当前页条数:{}", currentsize);
//数据列表:search.getsearchhits() for出每一条,然后加到list中
for (searchhit<map> searchhit : search.getsearchhits()) {
system.out.println("单条文档的原数据 = " + searchhit.getcontent());
system.out.println("单条文档的id = " + searchhit.getid());
system.out.println("单条文档的评分 = " + searchhit.getscore());
system.out.println("单条文档索引名(表名) = " + searchhit.getindex());//298_ops-web-js_1就是你输入的索引库名
}
}
//布尔查询
@postmapping("/es/boolquerybuilder")
public void boolquerybuilder() {
boolquerybuilder boolquerybuilder = querybuilders.boolquery();
//must 必须满足且参与算分
boolquerybuilder.must(querybuilders.matchquery("bsversion", "114"));
//mustnot 必须不满足 appid 300-700之间不参与查询(就是直接筛掉了)
boolquerybuilder.mustnot(querybuilders.rangequery("appid").gte("300").lte("700"));
//filter 必须满足,且不参与算分
// boolquerybuilder.filter(querybuilders.termquery("agentid", "298_ead348abbaf30f48"));
nativesearchquery dsl = new nativesearchquery(boolquerybuilder);
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
for (searchhit<map> searchhit : search.getsearchhits()) {
system.out.println("单条文档的原数据 = " + searchhit.getcontent());
system.out.println("单条文档的id = " + searchhit.getid());
system.out.println("单条文档的评分 = " + searchhit.getscore());
system.out.println("单条文档索引名(表名) = " + searchhit.getindex());//298_ops-web-js_1就是你输入的索引库名
}
}
//算分函数查询
@postmapping("/es/functionscorequerybuilder")
public void functionscorequerybuilder() {
functionscorequerybuilder functionscorequerybuilder = querybuilders.functionscorequery(
//原始查询
querybuilders.matchallquery(),
//算分数组
new functionscorequerybuilder.filterfunctionbuilder[]{
//第一个元素
new functionscorequerybuilder.filterfunctionbuilder(
//过滤器
querybuilders.matchquery("bsversion", "114"),
//权重
scorefunctionbuilders.weightfactorfunction(10)
),
//第二个元素
new functionscorequerybuilder.filterfunctionbuilder(
//过滤器
querybuilders.matchquery("bsversion", "115"),
//权重
scorefunctionbuilders.weightfactorfunction(10)
)
}).boostmode(combinefunction.replace);
nativesearchquery dsl = new nativesearchquery(functionscorequerybuilder);
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
for (searchhit<map> searchhit : search.getsearchhits()) {
system.out.println("单条文档的原数据 = " + searchhit.getcontent());
system.out.println("单条文档的id = " + searchhit.getid());
system.out.println("单条文档的评分 = " + searchhit.getscore());
system.out.println("单条文档索引名(表名) = " + searchhit.getindex());//298_ops-web-js_1就是你输入的索引库名
}
}
//范围查询
@postmapping("/es/rangequery")
public void rangequery() {
//范围查询 appid字段 >=0 <=200 的数据
rangequerybuilder rangequerybuilder = querybuilders.rangequery("appid").gte("0").lte("200");
nativesearchquery dsl = new nativesearchquery(rangequerybuilder);
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
for (searchhit<map> searchhit : search.getsearchhits()) {
system.out.println("单条文档的原数据 = " + searchhit.getcontent());
system.out.println("单条文档的id = " + searchhit.getid());
system.out.println("单条文档的评分 = " + searchhit.getscore());
system.out.println("单条文档索引名(表名) = " + searchhit.getindex());//298_ops-web-js_1就是你输入的索引库名
}
}
//精确查询
@postmapping("/es/termquery")
public void termquery() {
//根据isp字段 精确查询 内网ip
termsquerybuilder termsquerybuilder = querybuilders.termsquery("isp", " 内网ip ");
nativesearchquery dsl = new nativesearchquery(termsquerybuilder);
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
for (searchhit<map> searchhit : search.getsearchhits()) {
system.out.println("单条文档的原数据 = " + searchhit.getcontent());
system.out.println("单条文档的id = " + searchhit.getid());
system.out.println("单条文档的评分 = " + searchhit.getscore());
system.out.println("单条文档索引名(表名) = " + searchhit.getindex());//298_ops-web-js_1就是你输入的索引库名
}
}
//多字段查询
@postmapping("/es/multimatchquery")
public void multimatchquery() {
//备注:字段必须是text类型,可以分词类型!!!!
//查找keyword、数值、日期、boolean等会报错!!!
//如果放入精确类型的字段,会报错!!!!
multimatchquerybuilder multimatchquery = querybuilders.multimatchquery("114", "bsversion", "type");//查询114根据"bsversion","type"
nativesearchquery dsl = new nativesearchquery(multimatchquery);
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
for (searchhit<map> searchhit : search.getsearchhits()) {
system.out.println("单条文档的原数据 = " + searchhit.getcontent());
system.out.println("单条文档的id = " + searchhit.getid());
system.out.println("单条文档的评分 = " + searchhit.getscore());
system.out.println("单条文档索引名(表名) = " + searchhit.getindex());//298_ops-web-js_1就是你输入的索引库名
}
}
//单字段查询
@postmapping("/es/matchquery")
public void matchquery() {
matchquerybuilder matchquery = querybuilders.matchquery("bsversion", "114");
nativesearchquery dsl = new nativesearchquery(matchquery);
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
for (searchhit<map> searchhit : search.getsearchhits()) {
system.out.println("单条文档的原数据 = " + searchhit.getcontent());
system.out.println("单条文档的id = " + searchhit.getid());
system.out.println("单条文档的评分 = " + searchhit.getscore());
system.out.println("单条文档索引名(表名) = " + searchhit.getindex());//298_ops-web-js_1就是你输入的索引库名
}
}
//查询所有
@postmapping("/es/matchallquery")
public void matchallquery() {
matchallquerybuilder matchallquery = querybuilders.matchallquery();
nativesearchquery dsl = new nativesearchquery(matchallquery);
searchhits<map> search = elasticsearchresttemplate.search(dsl, map.class, indexcoordinates.of("298_ops-web-js_1"));
log.info("总条数:{}", search.gettotalhits());
log.info("查询原始对象:{}", search.getsearchhits());
log.info("分数值:{}", search.getmaxscore());
log.info("有无聚合:{}", search.hasaggregations());
log.info("返回搜索命中数量的关系,例如精确值、估计值:{}", search.gettotalhitsrelation());
log.info("判断是否存在搜索命中结果:{}", search.hassearchhits());
//原始结果的每一条数据
for (searchhit<map> searchhit : search.getsearchhits()) {
system.out.println("单条文档 = " + searchhit);
system.out.println("单条文档的原数据 = " + searchhit.getcontent());
}
}
}
————————————————————————————————————
发表评论