目录
一、业务搜索核心功能
二、高级搜索匹配功能
三、搜索排序功能
elasticsearch高级搜索功能多维度分享,这也是实战的比较之路,此次我们全面分享常用的业务情景,全覆盖功能分享,让大家有一览众山小的感觉,废话少数,现在开始!
1、返回指定字段
GET /nandao_scenic/_search
{
"_source": ["title","city"],
"query": {
"term": {
"city": {
"value": "北京市"
}
}
}
}
java 语言
public List getScenicField(String keyword) {
SearchRequest searchRequest = new SearchRequest("scenic");//客户端请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//创建搜索builder
searchSourceBuilder.query(new TermQueryBuilder("city", keyword));//构建query
searchSourceBuilder.fetchSource(new String[]{"title", "city"}, null);//设定希望返回的字段数组
// searchSourceBuilder.from(20);
// searchSourceBuilder.size(10);
searchRequest.source(searchSourceBuilder);
List resultList = new ArrayList();
try {
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);//执行搜索
return resultList;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
2、结果计数
GET /nandao_scenic/_count
{
"query": {
"term": {
"city": {
"value": "北京市"
}
}
}
}
java语言
public long getCityCount() {
CountRequest countRequest = new CountRequest("scenic");//客户端count请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//创建搜索builder
searchSourceBuilder.query(new TermQueryBuilder("city", "北京"));//构建query
countRequest.source(searchSourceBuilder);//设置查询
try {
CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);//执行count
return countResponse.getCount();//返回count结果
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
3、结果分页
GET /nandao_scenic/_search
{
"from": 0,
"size": 20,
"query": {
"term": {
"city": {
"value": "北京市"
}
}
}
}
设置分页最大值:
PUT /nandao_scenic/_settings
{
"index":{
"max_result_window":10001
}
}
es不适合深度分页,影响性能。
java语言
public List getScenicField(String keyword) {
SearchRequest searchRequest = new SearchRequest("scenic");//客户端请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//创建搜索builder
searchSourceBuilder.query(new TermQueryBuilder("city", keyword));//构建query
searchSourceBuilder.fetchSource(new String[]{"title", "city"}, null);//设定希望返回的字段数组
searchSourceBuilder.from(20);
searchSourceBuilder.size(10);
searchRequest.source(searchSourceBuilder);
List resultList = new ArrayList();
try {
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);//执行搜索
return resultList;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
4、性能分析:开启
GET /nandao_scenic/_search
{
"profile": "true",
"query": {
"term": {
"city": {
"value": "北京市"
}
}
}
}
5、评分分析
GET /nandao_scenic/_explain/003
{
"query": {
"term": {
"city": {
"value": "北京市"
}
}
}
}
1、查询所有文档
GET /nandao_scenic/_search
{
"_source": ["title","city"],
"query": {
"match_all": {
"boost": 2
}
}
}
java客户端
public void matchAllSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery().boost(2.0f);//新建match_all查询,并设置boost值为2.0
searchSourceBuilder.query(matchAllQueryBuilder);
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
public void printResult(SearchRequest searchRequest) {
try {
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);//执行搜索
SearchHits searchHits = searchResponse.getHits();//获取搜索结果集
for (SearchHit searchHit : searchHits) {//遍历搜索结果集
String index = searchHit.getIndex();//获取索引名称
String id = searchHit.getId();//获取文档_id
Float score = searchHit.getScore();//获取得分
String source = searchHit.getSourceAsString();//获取文档内容
System.out.println("index=" + index + ",id=" + id + ",score=" + score + ",source=" + source);//打印数据
}
} catch (Exception e) {
e.printStackTrace();
}
}
2、term 级别查询
2.1、term 查询
GET /nandao_scenic/_search
{
"query": {
"term": {
"city": {
"value": "北京市"
}
}
}
}
2.2、terms查询
GET /nandao_scenic/_search
{
"query": {
"terms": {
"city": [
"北京市",
"河南"
]
}
}
}
java客户端
public void termsSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//创建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termsQuery("city", "北京", "天津"));//构建terms查询
searchRequest.source(searchSourceBuilder);//设置查询请求
printResult(searchRequest);//打印搜索结果
}
2.3、range查询
GET /nandao_scenic/_search
{
"query": {
"range": {
"price": {
"gte":50,
"lte":100
}
}
}
}
java语言客户端
public void rangeSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//创建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建range查询
QueryBuilder queryBuilder = QueryBuilders.rangeQuery("create_time").gte("20220115120000").lte("20220116120000");
searchSourceBuilder.query(queryBuilder);
searchRequest.source(searchSourceBuilder);//设置查询请求
printResult(searchRequest);//打印搜索结果
}
2. 4、exists 查询
GET /nandao_scenic/_search
{
"query": {
"exists": {
"field": "tag"
}
}
}
java语言
public void existsSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.existsQuery("tag"));
searchRequest.source(searchSourceBuilder);
printResult(searchRequest);
}
3、布尔类型
3.1、must查询
GET /nandao_scenic/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"city": {
"value": "北京市"
}
}
},
{
"range": {
"price": {
"gte": 10,
"lte": 220
}
}
}
]
}
}
}
java语言
public void mustSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//新建请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
TermQueryBuilder termQueryIsReady = QueryBuilders.termQuery("city", "北京");//构建城市term查询
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte(350).lte(400);//构建价格range查询
boolQueryBuilder.must(termQueryIsReady).must(rangeQueryBuilder);//进行关系“与”查询
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
3.2、should查询
GET /nandao_scenic/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"city": {
"value": "北京市"
}
}
},
{
"term": {
"city": {
"value": "北京市"
}
}
}
]
}
}
}
java语言
public void shouldSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
TermQueryBuilder termQueryIsReady = QueryBuilders.termQuery("city", "北京");//构建城市为“北京”的term查询
TermQueryBuilder termQueryWritter = QueryBuilders.termQuery("city", "天津");//构建城市为“天津”的term查询
boolQueryBuilder.should(termQueryIsReady).should(termQueryWritter);//进行关系“或”查询
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
3.3、must not 查询
GET /nandao_scenic/_search
{
"query": {
"bool": {
"must_not": [
{
"term": {
"city": {
"value": "北京市"
}
}
},
{
"term": {
"city": {
"value": "河南"
}
}
}
]
}
}
}
java客户端
public void mustNotSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
TermQueryBuilder termQueryIsReady = QueryBuilders.termQuery("city", "北京");//构建城市为“北京”的term查询
TermQueryBuilder termQueryWritter = QueryBuilders.termQuery("city", "天津");//构建城市为“天津”的term查询
boolQueryBuilder.mustNot(termQueryIsReady).mustNot(termQueryWritter);//进行关系“必须不”查询
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
3.4、filter 查询
GET /nandao_scenic/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"city": {
"value": "北京市"
}
}
},
{
"term": {
"full": true
}
}
]
}
}
}
java客户端
public void filterSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.filter(QueryBuilders.termQuery("city", "北京"));
boolQueryBuilder.filter(QueryBuilders.termQuery("full", false));
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
printResult(searchRequest);
}
4、Constant Scope 查询
GET /nandao_scenic/_search
{
"_source": ["city"],
"query": {
"constant_score": {
"filter": {
"match":{
"city":"北京市"
}
}
}
}
}
java语言
public void constantScoreSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
ConstantScoreQueryBuilder constantScoreQueryBuilder = new ConstantScoreQueryBuilder(QueryBuilders.termQuery("amenities", "停车场"));//构建城市为“北京”的term查询
searchSourceBuilder.query(constantScoreQueryBuilder);
constantScoreQueryBuilder.boost(2.0f);
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
5、Function score 查询
GET /nandao_scenic/_search
{
"_source": ["city"],
"query": {
"function_score": {
"query": {
"term": {
"city": {
"value": "北京市"
}
}
},
"functions": [
{
"random_score": {}
}
],
"score_mode": "sum"
}
}
}
java语言
public void functionScoreSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//创建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
TermQueryBuilder termQuery = QueryBuilders.termQuery("city", "北京");//构建term查询
ScoreFunctionBuilder> scoreFunction = ScoreFunctionBuilders.randomFunction();//构建随机函数
//构建function_score查询
FunctionScoreQueryBuilder funcQuery = QueryBuilders.functionScoreQuery(termQuery, scoreFunction).boostMode(CombineFunction.SUM);
searchSourceBuilder.query(funcQuery);
searchRequest.source(searchSourceBuilder);//设置查询请求
printResult(searchRequest);//打印搜索结果
}
6、全文搜索
6.1、match 查询:只要包含一个字就能搜出来
GET /nandao_scenic/_search
{
"_source": ["title"],
"query": {
"match": {
"title": "水山寺"
}
}
}
java客户端
public void matchSearch() {
SearchRequest searchRequest = new SearchRequest();//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("title", "山水寺").operator(Operator.AND));//新建match查询,并设置operator值为and
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
6.2、multi_match 查询
GET /nandao_scenic/_search
{
"_source": ["title","city"],
"query": {
"multi_match": {
"query": "山市",
"fields": [
"city",
"title"
]
}
}
}
java客户端
public void multiMatchSearch() {
SearchRequest searchRequest = new SearchRequest();//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("山市", "title", "city"));//新建multi_match查询,从"title"和"amenities"字段查询"假日"
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
6.3、multi_phrase 查询
GET /nandao_scenic/_search
{
"query": {
"match_phrase": {
"title": "台山"
}
}
}
java语言
public void matchPhraseSearch() {
SearchRequest searchRequest = new SearchRequest();//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchPhraseQuery( "title", "台山").slop(2));
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
7、基于地理位置查询
GET /nandao_scenic/_search
{
"_source": ["title","city"],
"query": {
"geo_distance": {
"distance": "5km",
"location":{
"lat":"34.333",
"lon":"23.56"
}
}
}
}
java 客户端
public void geoDistanceSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//新建geo_distance查询,设置基准点坐标和周边距离
searchSourceBuilder.query(QueryBuilders.geoDistanceQuery("location").distance(5, DistanceUnit.KILOMETERS).point(40.026919, 116.47473));
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
多边形:
GET /nandao_scenic/_search
{
"query": {
"geo_polygon": {
"location":{
"points":[
{
"lat":"39.959829",
"lon":"116.417088"
},
{
"lat":"39.960272",
"lon":"116.432035"
},
{
"lat":"39.965802",
"lon":"116.421399"
}
]
}
}
}
}
java语言
public void geoPolygonSearch() {
SearchRequest searchRequest = new SearchRequest("scenic");//新建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//新建geo_distance查询,设置基准点坐标和周边距离
List geoPointList = new ArrayList();//新建多边形顶点列表
//添加多边形顶点
geoPointList.add(new GeoPoint(39.959829, 116.417088));
geoPointList.add(new GeoPoint(39.960272, 116.432035));
geoPointList.add(new GeoPoint(39.965802, 116.421399));
searchSourceBuilder.query(QueryBuilders.geoPolygonQuery("location", geoPointList));//新建geo_polygon查询
searchRequest.source(searchSourceBuilder);//设置查询
printResult(searchRequest);//打印结果
}
8、实战场景之一:京东搜索商品,前缀查询
PUT /nandao_scenic_sug
{
"mappings": {
"properties": {
"query_word":{
"type": "completion"
}
}
}
}
查询
GET /nandao_scenic_sug/_search
{
"suggest": {
"scenic_zh_sug": {
"prefix":"北京",
"completion": {
"field": "query_word"
}
}
}
}
java语言
public void suggestSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("nandao_scenic_sug");//创建搜索请求,指定索引名称为scenic_sug
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//创建completion类型搜索建议
CompletionSuggestionBuilder comSuggest = SuggestBuilders.completionSuggestion("query_word").prefix("北京");
SuggestBuilder suggestBuilder = new SuggestBuilder();
suggestBuilder.addSuggestion("scenic_zh_sug", comSuggest);//添加搜索建议,"scenic_zh_sug"为自定义名称
searchSourceBuilder.suggest(suggestBuilder);//设置suggest请求
searchRequest.source(searchSourceBuilder);//设置查询请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);//进行搜索,获取搜索结果
CompletionSuggestion suggestion = response.getSuggest().getSuggestion("scenic_zh_sug");//获取suggest结果
System.out.println("sug result:");
//遍历suggest结果,并进行打印
for (CompletionSuggestion.Entry.Option option : suggestion.getOptions()) {
System.out.println("sug:" + option.getText().string());
}
}
1、按照普通字段排序
GET /nandao_scenic/_search
{
"_source": ["title","city","price"],
"query": {
"match": {
"title": "山"
}
},
"sort": [
{
"price": {
"order": "desc"
},
"city": {
"order": "desc"
}
}
]
}
java客户端
public void commonSort() {
SearchRequest searchRequest = new SearchRequest("nandao_scenic");//创建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("title", "山"));//构建match查询
searchRequest.source(searchSourceBuilder);//设置查询请求
searchSourceBuilder.sort("price", SortOrder.DESC);//设置按照价格降序
searchSourceBuilder.sort("praise", SortOrder.DESC);//设置按照口碑值降序
printResult(searchRequest);//打印搜索结果
}
2、按照地理位置排序
GET /nandao_scenic/_search
{
"_source": ["title","city","location"],
"query": {
"geo_distance": {
"distance": "5km",
"location":{
"lat":"34.333",
"lon":"23.56"
}
}
},
"sort": [
{
"geo_distance": {
"location":{
"lat":"34.333",
"lon":"23.56"
},
"order": "desc",
"unit":"km",
"distance_type":"plane"
}
}
]
}
java客户端
public void geoDistanceSearchSort() throws IOException {
SearchRequest searchRequest = new SearchRequest("nandao_scenic");//创建搜索请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//创建geo_distance查询,搜索距离中心点5公里范围内的酒店
searchSourceBuilder.query(QueryBuilders.geoDistanceQuery("location").distance(5, DistanceUnit.KILOMETERS).point(39.915143, 116.4039));
//创建geo_distance_sort排序,设定按照与中心点的距离升序排序
GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort("location", 39.915143, 116.4039)
.point(39.915143, 116.4039).unit(DistanceUnit.KILOMETERS).order(SortOrder.ASC);
searchSourceBuilder.sort(geoDistanceSortBuilder);//设置排序规则
searchRequest.source(searchSourceBuilder);//设置查询
//开始搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits searchHits = searchResponse.getHits();//获取搜索结果
System.out.println("search result distance sort:");
//开始遍历搜索结果
for (SearchHit searchHit : searchHits) {
//得到酒店距离中心点的距离
double geoDistance = (double) searchHit.getSortValues()[0];
//以Map形式获取文档_source内容
Map sourceMap = searchHit.getSourceAsMap();
Object title = sourceMap.get("title");
Object city = sourceMap.get("city");
//打印结果
System.out.println("title=" + title + ",city=" + city + ",geoDistance:" + geoDistance);
}
}
到此,es高级搜索功能分享完毕,大家一定要多多练习,定会很快掌握,下篇我们分享文本搜索相关功能,敬请期待!