【ES常用查询】基于ElasticsearchRestTemplate及NativeSearchQuery的查询
包含当前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 {
/**
* 测试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());
}
}
}
————————————————————————————————————