微服务day09
DSL查询
快速入门
GET /items/_search
{
"query": {
"match_all": {}
}
}
叶子查询
GET /items/_search
{
"query": {
"match_all": {}
}
}
GET /items/_search
{
"query": {
"multi_match": {
"query": "脱脂牛奶",
"fields": ["name"]
}
}
}
GET /items/_search
{
"query": {
"term": {
"price": {
"value": "80900"
}
}
}
}
GET /items/_search
{
"query": {
"range": {
"price": {
"gte": 100000,
"lte": 1000000
}
}
}
}
GET /items/_search
{
"query": {
"ids": {
"values": ["688000","1861100"]
}
}
}
复合查询
案例
GET /items/_search
{
"query": {
"bool": {
"must": [
{
"match":{
"name":"智能手机"
}
}
],
"filter": [
{
"term":{
"brand":"华为"
}
},
{
"range": {
"price": {
"gte": 90000,
"lte": 159900
}
}
}
]
}
}
}
排序和分页
排序案例
GET /items/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"sold": {
"order": "desc"
}
},
{
"price":{
"order": "asc"
}
}
]
}
#排序简写
GET /items/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"sold": "desc"
},
{
"price": "asc"
}
]
}
分页
分页案例
#排序分页
GET /items/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"sold": "desc"
},
{
"price": "asc"
}
],
"from": 0,
"size": 10
}
高亮显示
默认情况下添加的标签就是 em。
返回值将高亮字段放在highlight中,不会修改源数据。
GET /items/_search
{
"query": {
"multi_match": {
"query": "脱脂牛奶",
"fields": ["name"]
}
},
"highlight": {
"fields": {
"name":{
"pre_tags": "<em>",
"post_tags": "</em>"
}
}
}
}
GET /items/_search
{
"query": {
"multi_match": {
"query": "脱脂牛奶",
"fields": ["name"]
}
},
"highlight": {
"fields": {
"name":{}
}
}
}
查询结果相同。
结果:
{
"_index" : "items",
"_type" : "_doc",
"_id" : "12179607155",
"_score" : 22.290178,
"_source" : {
"id" : "12179607155",
"name" : """【沃尔玛】艾思达/ASDA纯牛奶 灭菌乳 早餐奶 牛奶 英国 进口 全脂\脱脂\部分脱脂 部分脱脂牛奶 1L*6""",
"price" : 96300,
"image" : "https://m.360buyimg.com/mobilecms/s720x720_jfs/t5977/320/3555243042/134144/38730483/59546920Nbe3ddc70.jpg!q70.jpg.webp",
"category" : "牛奶",
"brand" : "ASDA",
"sold" : 0,
"commentCount" : 0,
"isAD" : false,
"updateTime" : 1556640000000
},
"highlight" : {
"name" : [
"""【沃尔玛】艾思达/ASDA纯<em>牛</em><em>奶</em> 灭菌乳 早餐<em>奶</em> <em>牛</em><em>奶</em> 英国 进口 全<em>脂</em>\<em>脱</em><em>脂</em>\部分<em>脱</em><em>脂</em> 部分<em>脱</em><em>脂</em><em>牛</em><em>奶</em> 1L*6"""
]
}
},
查询总结
JavaRestClient
快速入门
@org.junit.jupiter.api.Test
public void testList() throws IOException {
//创建对象
SearchRequest searchRequest = new SearchRequest("items");
//构建DSL
searchRequest.source().query(QueryBuilders.matchAllQuery());
//发送请求
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
//解析响应
SearchHits hits = search.getHits();
long value = hits.getTotalHits().value;
System.out.println(value);
SearchHit[] hits1 = hits.getHits();
for (SearchHit hit : hits1) {
String json = hit.getSourceAsString();
ItemDoc bean = JSONUtil.toBean(json, ItemDoc.class);
System.out.println(bean);
}
}
构造查询条件
案例
两种写法:
//复杂条件查询
@org.junit.jupiter.api.Test
public void testbool() throws IOException {
// //创建对象
SearchRequest searchRequest = new SearchRequest("items");
//创建bool对象
// //构建DSL
BoolQueryBuilder query = new BoolQueryBuilder();
//添加must查询
query.must(QueryBuilders.matchQuery("name","脱脂牛奶"));
//添加两个filter查询
query.filter(QueryBuilders.termQuery("brand","德亚"));
query.filter(QueryBuilders.rangeQuery("price").lt(30000));
searchRequest.source().query(query);
//发送请求
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
//解析响应
SearchHits hits = search.getHits();
long value = hits.getTotalHits().value;
System.out.println(value);
SearchHit[] hits1 = hits.getHits();
for (SearchHit hit : hits1) {
String json = hit.getSourceAsString();
ItemDoc bean = JSONUtil.toBean(json, ItemDoc.class);
System.out.println(bean);
}
}
@Test
void testBool() throws IOException {
// 1.创建Request
SearchRequest request = new SearchRequest("items");
// 2.组织请求参数
// 2.1.准备bool查询
BoolQueryBuilder bool = QueryBuilders.boolQuery();
// 2.2.关键字搜索
bool.must(QueryBuilders.matchQuery("name", "脱脂牛奶"));
// 2.3.品牌过滤
bool.filter(QueryBuilders.termQuery("brand", "德亚"));
// 2.4.价格过滤
bool.filter(QueryBuilders.rangeQuery("price").lte(30000));
request.source().query(bool);
// 3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 4.解析响应
// handleResponse(response);
//解析响应
SearchHits hits = response.getHits();
long value = hits.getTotalHits().value;
System.out.println(value);
SearchHit[] hits1 = hits.getHits();
for (SearchHit hit : hits1) {
String json = hit.getSourceAsString();
ItemDoc bean = JSONUtil.toBean(json, ItemDoc.class);
System.out.println(bean);
}
}
排序和分页
@org.junit.jupiter.api.Test
public void testSoudAndPage() throws IOException {
int pageNum = 2;
int pageSize = 5;
//创建对象
SearchRequest searchRequest = new SearchRequest("items");
//构建DSL
//设置分页和排序
searchRequest.source().query(QueryBuilders.matchAllQuery())
.from((pageNum-1)*pageSize).size(pageSize)
.sort("sold", SortOrder.DESC)
.sort("price",SortOrder.ASC);
//发送请求
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
//解析响应
SearchHits hits = search.getHits();
long value = hits.getTotalHits().value;
System.out.println(value);
SearchHit[] hits1 = hits.getHits();
for (SearchHit hit : hits1) {
String json = hit.getSourceAsString();
ItemDoc bean = JSONUtil.toBean(json, ItemDoc.class);
System.out.println(bean);
}
}
高亮显示
@org.junit.jupiter.api.Test
public void testHighLight() throws IOException {
//创建对象
SearchRequest searchRequest = new SearchRequest("items");
//构建DSL
searchRequest.source().query(QueryBuilders.matchQuery("name","脱脂牛奶"));
//设置高亮,两种都可以,第二种的底层就是第一种
// searchRequest.source().highlighter(new HighlightBuilder().field("name"));
searchRequest.source().highlighter(SearchSourceBuilder.highlight().field("name"));
//发送请求
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
//解析响应
SearchHits hits = search.getHits();
long value = hits.getTotalHits().value;
System.out.println(value);
SearchHit[] hits1 = hits.getHits();
for (SearchHit hit : hits1) {
String json = hit.getSourceAsString();
ItemDoc bean = JSONUtil.toBean(json, ItemDoc.class);
//获取高亮显示的字段,并写入对象中
Map<String, HighlightField> hgf = hit.getHighlightFields();
//判断是否存在
if (CollUtil.isNotEmpty(hgf)){
//存在高亮字段
//根距key获取数据
HighlightField hf = hgf.get("name");
if (hf != null){
//在添加高亮时如果字段过长就会断成几部分使用数组返回
Text[] fragments = hf.getFragments();
String string = fragments[0].string();
//将高亮字段进行替换
bean.setName(string);
}
}
System.out.println(bean);
}
}
数据聚合
DSL聚合
由于出现问题详见:https://b11et3un53m.feishu.cn/wiki/WtCmwJQQDijsBikYLviceT9lnke
@Test
void testAgg() throws IOException {
// 1.创建Request
SearchRequest request = new SearchRequest("items");
// 2.准备请求参数
BoolQueryBuilder bool = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("category", "手机"))
.filter(QueryBuilders.rangeQuery("price").gte(300000));
request.source().query(bool).size(0);
// 3.聚合参数
request.source().aggregation(
AggregationBuilders.terms("brand_agg").field("brand").size(5)
);
// 4.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 5.解析聚合结果
Aggregations aggregations = response.getAggregations();
// 5.1.获取品牌聚合
Terms brandTerms = aggregations.get("brand_agg");
// 5.2.获取聚合中的桶
List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
// 5.3.遍历桶内数据
for (Terms.Bucket bucket : buckets) {
// 5.4.获取桶内key
String brand = bucket.getKeyAsString();
System.out.print("brand = " + brand);
long count = bucket.getDocCount();
System.out.println("; count = " + count);
}
}