当前位置: 首页 > news >正文

Elasticseach RestClient Api

Elasticsearch RestclientApi基础用法
查询
索引库
初始化

添加依赖

<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

创建链接

package com.hmall.item.es;import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;import java.io.IOException;import static org.junit.jupiter.api.Assertions.*;/*** @ Author qwh* @ Date 2024/6/19 8:51*/class itemApplicationTest {private RestHighLevelClient client;//创建链接@BeforeEachvoid setup(){this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.70.145:9200")));}//测试链接@Testvoid testConnect(){System.out.println(client);}//关闭链接@AfterEachvoid destroy() throws IOException {this.client.close();}}
创建索引库
PUT /索引库名称
{"mappings": {"properties": {"字段名":{"type": "text","analyzer": "ik_smart"},"字段名2":{"type": "keyword","index": "false"},"字段名3":{"properties": {"子字段": {"type": "keyword"}}},// ...略}}
}
    @Testvoid CreateIndex() throws IOException {//1CreateIndexRequest request = new CreateIndexRequest("items");//2request.source(MAPPING_TEMPLATE, XContentType.JSON);//3client.indices().create(request, RequestOptions.DEFAULT);}static final String MAPPING_TEMPLATE = "{\n" +"  \"mappings\": {\n" +"    \"properties\": {\n" +"      \"id\": {\n" +"        \"type\": \"keyword\"\n" +"      },\n" +"      \"name\":{\n" +"        \"type\": \"text\",\n" +"        \"analyzer\": \"ik_max_word\"\n" +"      },\n" +"      \"price\":{\n" +"        \"type\": \"integer\"\n" +"      },\n" +"      \"stock\":{\n" +"        \"type\": \"integer\"\n" +"      },\n" +"      \"image\":{\n" +"        \"type\": \"keyword\",\n" +"        \"index\": false\n" +"      },\n" +"      \"category\":{\n" +"        \"type\": \"keyword\"\n" +"      },\n" +"      \"brand\":{\n" +"        \"type\": \"keyword\"\n" +"      },\n" +"      \"sold\":{\n" +"        \"type\": \"integer\"\n" +"      },\n" +"      \"commentCount\":{\n" +"        \"type\": \"integer\"\n" +"      },\n" +"      \"isAD\":{\n" +"        \"type\": \"boolean\"\n" +"      },\n" +"      \"updateTime\":{\n" +"        \"type\": \"date\"\n" +"      }\n" +"    }\n" +"  }\n" +"}";
删除索引库
DELETE /索引库名
    //删除索引库@Testvoid DeleteIndex() throws IOException {//创建请求对象DeleteIndexRequest items = new DeleteIndexRequest("items");//发送请求client.indices().delete(items,RequestOptions.DEFAULT);}
判断索引库是否存在
GET /索引库名
    @Testvoid GetIndex() throws IOException {//发送请求GetIndexRequest items = new GetIndexRequest("items");boolean exists = client.indices().exists(items, RequestOptions.DEFAULT);System.out.println(exists ? "索引库已经存在" : "索引不存在");}
文档
新增文档
  1. 实体类
package com.hmall.item.domain.po;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.time.LocalDateTime;@Data
@ApiModel(description = "索引库实体")
public class ItemDoc{@ApiModelProperty("商品id")private String id;@ApiModelProperty("商品名称")private String name;@ApiModelProperty("价格(分)")private Integer price;@ApiModelProperty("商品图片")private String image;@ApiModelProperty("类目名称")private String category;@ApiModelProperty("品牌名称")private String brand;@ApiModelProperty("销量")private Integer sold;@ApiModelProperty("评论数")private Integer commentCount;@ApiModelProperty("是否是推广广告,true/false")private Boolean isAD;@ApiModelProperty("更新时间")private LocalDateTime updateTime;
}
  1. api语法
POST /{索引库名}/_doc/1
{"name": "Jack","age": 21
}    
  1. java
  • 1)创建Request对象,这里是IndexRequest,因为添加文档就是创建倒排索引的过程
  • 2)准备请求参数,本例中就是Json文档
  • 3)发送请求
package com.hmall.item.es;import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmall.common.utils.CollUtils;
import com.hmall.item.domain.po.Item;
import com.hmall.item.domain.po.ItemDoc;
import com.hmall.item.service.IItemService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;
import java.util.List;/*** @ Author qwh* @ Date 2024/6/19 9:29*/
@Slf4j
@SpringBootTest(properties = "spring.profiles.active=local")
public class itemDocTest {private RestHighLevelClient client;@Autowiredprivate IItemService iItemService;@BeforeEachvoid setup(){client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.70.145:9200")));}@Test //添加文档void addDocument() throws IOException {//根据id查询item 添加到esItem item = iItemService.getById(100002644680L);//转换为文档类型ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);//将文档类型转换为jsonString doc = JSONUtil.toJsonStr(itemDoc);System.out.println(doc.toString());// 1.准备Request对象IndexRequest request = new IndexRequest("items").id(itemDoc.getId());// 2.准备Json文档request.source(doc, XContentType.JSON);// 3.发送请求client.index(request, RequestOptions.DEFAULT);}@AfterEachvoid destroy() throws IOException {this.client.close();}
}
查询文档
  1. api
GET /{索引库名}/_doc/{id}
  1. java
  • 1)准备Request对象。这次是查询,所以是GetRequest
  • 2)发送请求,得到结果。因为是查询,这里调用client.get()方法
  • 3)解析结果,就是对JSON做反序列化
    @Testvoid GetDocument() throws IOException {GetRequest request = new GetRequest("items").id("100002644680");//发送请求GetResponse response = client.get(request, RequestOptions.DEFAULT);//获取相应结果String json = response.getSourceAsString();ItemDoc itemDoc = JSONUtil.toBean(json, ItemDoc.class);System.out.println("itemDoc"+itemDoc);}
删除文档
  1. api
DELETE /{索引库}/_doc/{id}
  1. java
  • 1)准备Request对象,因为是删除,这次是DeleteRequest对象。要指定索引库名和id
  • 2)准备参数,无参,直接省略
  • 3)发送请求。因为是删除,所以是client.delete()方法
    @Testvoid deleteDocument() throws IOException {//准备request 参数 索引库名 文档idDeleteRequest request = new DeleteRequest("items", "100002644680");client.delete(request,RequestOptions.DEFAULT);}
修改文档
  • 全量修改:本质是先根据id删除,再新增
  • 局部修改:修改文档中的指定字段值
  1. api 局部修改
POST /{索引库名}/_update/{id}
{"doc": {"字段名": "字段值","字段名": "字段值"}
}
  1. java
  • 1)准备Request对象。这次是修改,所以是UpdateRequest
  • 2)准备参数。也就是JSON文档,里面包含要修改的字段
  • 3)更新文档。这里调用client.update()方法
    //修改文档@Testvoid updateDocument() throws IOException {//requestUpdateRequest request = new UpdateRequest("items", "100002644680");//修改内容request.doc("price",99999,"commentCount",1);//发送请求client.update(request,RequestOptions.DEFAULT);}
批量导入
  1. java
  • 创建Request,但这次用的是BulkRequest
  • 准备请求参数
  • 发送请求,这次要用到client.bulk()方法
//批量导入
@Test
void loadItemDocs() throws IOException {
//分页查询
int curPage = 1;
int size = 1000;
while (true){Page<Item> page = iItemService.lambdaQuery().eq(Item::getStatus, 1).page(new Page<>(curPage, size));//f非空校验List<Item> items = page.getRecords();if (CollUtils.isEmpty(items)) {return;}log.info("加载第{}页数据共{}条",curPage,items.size());//创建requestBulkRequest request = new BulkRequest("items");//准备参数for (Item item : items) {ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);request.add(new IndexRequest().id(itemDoc.getId()).source(JSONUtil.toJsonStr(itemDoc),XContentType.JSON));}//发送请求client.bulk(request,RequestOptions.DEFAULT);curPage++;
}
}

文档操作的基本步骤:

  • 初始化RestHighLevelClient
  • 创建XxxRequest。
    • XXX是Index、Get、Update、Delete、Bulk
  • 准备参数(Index、Update、Bulk时需要)
  • 发送请求。
    • 调用RestHighLevelClient#.xxx()方法,xxx是index、get、update、delete、bulk
  • 解析结果(Get时需要)
模糊查询
叶子查询
  • 基本语法
GET /{索引库名}/_search
{"query": {"查询类型": {// .. 查询条件}}
}
- GET /{索引库名}/_search:其中的_search是固定路径,不能修改
GET /items/_search
{"query": {"match_all": {}}
}
package com.hmall.item.es;import cn.hutool.json.JSONUtil;
import com.hmall.common.utils.CollUtils;
import com.hmall.item.domain.po.ItemDoc;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;import java.io.IOException;
import java.util.List;
import java.util.Map;/*** @ Author qwh* @ Date 2024/6/19 16:16*/
public class JavaAPITest {private RestHighLevelClient client;@BeforeEachvoid setup(){this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.70.145:9200")));}@Testvoid SearchMatchAll() throws IOException {//创建requestSearchRequest request = new SearchRequest("items");//请求参数request.source().query(QueryBuilders.matchAllQuery());//解析相应SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleResponse(response);}private void handleResponse(SearchResponse response) {SearchHits searchHits = response.getHits();// 1.获取总条数long total = searchHits.getTotalHits().value;System.out.println("共搜索到" + total + "条数据");// 2.遍历结果数组SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {// 3.得到_source,也就是原始json文档String source = hit.getSourceAsString();// 4.反序列化并打印ItemDoc item = JSONUtil.toBean(source, ItemDoc.class);System.out.println(item);}}@AfterEachvoid destroy() throws IOException {this.client.close();}
}


你会发现虽然是match_all,但是响应结果中并不会包含索引库中的所有文档,而是仅有10条。这是因为处于安全考虑,elasticsearch设置了默认的查询页数。

全文检索
  • 用分词器对用户输入搜索条件先分词,得到词条,然后再利用倒排索引搜索词条。例如:
    • match:
    • multi_match
  • 语法match:
GET /{索引库名}/_search
{"query": {"match": {"字段名": "搜索条件"}}
}实例 
查询名字里有荣耀的
GET /items/_search
{"query": {"match": {"name": "华为荣耀"}}
}
结果{"_index" : "items","_type" : "_doc","_id" : "21233662915","_score" : 18.592987,"_source" : {"id" : "21233662915","name" : "华为(HUAWEI) 华为 荣耀8 手机10 荣耀8X 智能手机 荣耀8X MAX 手机 荣耀8C 极光蓝 6GB+128GB","price" : 39900,"image" : "https://m.360buyimg.com/mobilecms/s720x720_jfs/t28714/124/965064480/118844/84e42061/5c036e18N0f680a90.jpg!q70.jpg.webp","category" : "手机","brand" : "华为","sold" : 0,"commentCount" : 0,"isAD" : false,"updateTime" : 1556640000000}},
    @Test //matchvoid matchQuery() throws IOException {//创建requestSearchRequest request = new SearchRequest("items");//请求参数request.source().query(QueryBuilders.matchQuery("name","华为"));//解析相应SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleResponse(response);}
  • multi_match
GET /{索引库名}/_search
{"query": {"multi_match": {"query": "搜索条件","fields": ["字段1", "字段2"]}}
}
例如
查询品牌和名称都又华为的
GET /items/_search
{"query": {"multi_match": {"query" : "华为","fields" : ["name","brand"]}}  
}"_source" : {"id" : "28922228139","name" : "华为(HUAWEI)华为P20手机 极光色 全网通(6GB+64GB)(华为直供,送礼包)","price" : 5100,"image" : "https://m.360buyimg.com/mobilecms/s720x720_jfs/t22243/131/709951731/332063/e5c95a29/5b15f92eN1f0677a5.jpg!q70.jpg.webp","category" : "手机","brand" : "华为","sold" : 0,"commentCount" : 0,"isAD" : false,"updateTime" : 1556640000000}}
@Test //multi_match
void multi_matchQuery() throws IOException {//创建requestSearchRequest request = new SearchRequest("items");//请求参数request.source().query(QueryBuilders.multiMatchQuery("name","华为","小米"));//解析相应SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleResponse(response);
}
精确查询
  • Term-level query不对用户输入搜索条件分词,根据字段内容精确值匹配。但只能查找keyword、数值、日期、boolean类型的字段。例如:ids term range 语法
  • term
GET /{索引库名}/_search
{"query": {"term": {"字段名": {"value": "搜索条件"}}}
}GET /items/_search
{"query": {"term": {"brand": {"value":"华为"}}}
}{"id" : "4093553","name" : "华为畅享7 Plus 3GB+32GB 普通版 香槟金 移动联通电信4G手机 双卡双待","price" : 26600,"image" : "https://m.360buyimg.com/mobilecms/s720x720_jfs/t7804/212/1308671016/161589/6dd9c5fc/599c0da5N88410391.jpg!q70.jpg.webp","category" : "手机","brand" : "华为","sold" : 0,"commentCount" : 0,"isAD" : false,"updateTime" : 1556640000000}}
@Test //term
void termQuery() throws IOException {//创建requestSearchRequest request = new SearchRequest("items");//请求参数 // 500-9999request.source().query(QueryBuilders.termQuery("brand","华为"));//解析相应SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleResponse(response);
}
  • range
range是范围查询,对于范围筛选的关键字有:
- gte:大于等于
- gt:大于
- lte:小于等于
- lt:小于GET /{索引库名}/_search
{"query": {"range": {"字段名": {"gte": {最小值},"lte": {最大值}}}}
}GET /items/_search
{"query": {"range": {"price": {"gte": 100,"lte": 2000}}}
}
{"id" : "1381868","name" : "ITO 拉杆箱20英寸旅行箱 商务时尚登机箱行李箱静音万向轮男女密码箱 CLASSIC 银色磨砂","price" : 900,"image" : "https://m.360buyimg.com/mobilecms/s720x720_jfs/t4591/120/2388880972/76319/a3cda346/58ef603bN91f7daf4.jpg!q70.jpg.webp","category" : "拉杆箱","brand" : "ITO","sold" : 0,"commentCount" : 0,"isAD" : false,"updateTime" : 1556640000000}}
@Test //range
void rangeQuery() throws IOException {//创建requestSearchRequest request = new SearchRequest("items");//请求参数 // 500-9999request.source().query(QueryBuilders.rangeQuery("price").gte(500).lte(9999));//解析相应SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleResponse(response);
}
  • bool查询
  • bool查询,即布尔查询。就是利用逻辑运算来组合一个或多个查询子句的组合。bool查询支持的逻辑运算有:
    • must:必须匹配每个子查询,类似“与”
    • should:选择性匹配子查询,类似“或”
    • must_not:必须不匹配,不参与算分,类似“非”
    • filter:必须匹配,不参与算分
    • 其中输入框的搜索条件肯定要参与相关性算分,可以采用match。但是价格范围过滤、品牌过滤、分类过滤等尽量采用filter,不要参与相关性算分
GET /items/_search
{"query": {"bool": { //查询方式"must": [  //查询条件1 与 名称必须为 小米{"match": {"name": "手机"}}],"should": [ 		//查询条件2 或 品牌为 小米 或者 vivo{"term": {"brand": { "value": "vivo" }}},{"term": {"brand": { "value": "小米" }}}],	//查询条件2 非 价格不是小于等于 2500的"must_not": [{"range": {"price": {"gte": 2500}}}],	"filter": [	//对于用户输入的关键字的搜索,都有匹配度相关问题,需要参与算分;对于过滤性的条件,一般不参与算分{"range": {"price": {"lte": 1000}}}]}}
}
// 搜索手机,但品牌必须是华为,价格必须是900~1599
GET /items/_search
{"query": {"bool": {"must": [{"match": {"name": "手机"}}],"filter": [{"term": {"brand": { "value": "华为" }}},{"range": {"price": {"gte": 90000, "lt": 159900}}}]}}
}
@Test //复合查询
void compareQuery() throws IOException {// 1.创建RequestSearchRequest 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);
}
  • elasticsearch默认是根据相关度算分(_score)来排序,但是也支持自定义方式对搜索结果排序。不过分词字段无法排序,能参与排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
GET /indexName/_search
{"query": {"match_all": {}},"sort": [{"排序字段": {"order": "排序方式asc和desc"}}]
}
查询 所有按照价格排序
GET /items/_search
{"query": {"match_all": {}},"sort": [{"price": {"order": "desc"}}]
}
  • 分页

elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参
elasticsearch中通过修改from、size参数来控制要返回的分页结果:

  • from:从第几个文档开始
  • size:总共查询几个文档

类似于mysql中的limit ?, ?

GET /items/_search
{"query": {"match_all": {}},"from": 0, // 分页开始的位置,默认为0"size": 10,  // 每页文档数量,默认10"sort": [{"price": {"order": "desc"}}]
}
@Test //排序和分页
void pageQuery() throws IOException {int pageNo = 1, pageSize = 5;// 1.创建RequestSearchRequest request = new SearchRequest("items");// 2.组织请求参数// 2.1.搜索条件参数request.source().query(QueryBuilders.matchQuery("name", "脱脂牛奶"));// 2.2.排序参数request.source().sort("price", SortOrder.ASC);// 2.3.分页参数request.source().from((pageNo - 1) * pageSize).size(pageSize);// 3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.解析响应handleResponse(response);
}
  • 深度分页

elasticsearch的数据一般会采用分片存储,也就是把一个索引中的数据分成N份,存储到不同节点上。这种存储方式比较有利于数据扩展,但给分页带来了一些麻烦。
比如一个索引库中有100000条数据,分别存储到4个分片,每个分片25000条数据。现在每页查询10条,查询第99页。那么分页查询的条件如下:

GET /items/_search
{"from": 990, // 从第990条开始查询"size": 10, // 每页查询10条"sort": [{"price": "asc"}]
}
  • 高亮
    • 高亮词条都被加了标签 标签都添加了红色样式
GET /{索引库名}/_search
{"query": {"match": {"搜索字段": "搜索关键字"}},"highlight": {"fields": {"高亮字段名称": {"pre_tags": "<em>","post_tags": "</em>"}}}
}
GET /items/_search
{"query": {"match": {"name": "华为"}},"highlight": {"fields": {"name": {"pre_tags": "<em>","post_tags": "</em>"}}}
}{"id" : "28922228139","name" : "华为(HUAWEI)华为P20手机 极光色 全网通(6GB+64GB)(华为直供,送礼包)","price" : 5100,"image" : "https://m.360buyimg.com/mobilecms/s720x720_jfs/t22243/131/709951731/332063/e5c95a29/5b15f92eN1f0677a5.jpg!q70.jpg.webp","category" : "手机","brand" : "华为","sold" : 0,"commentCount" : 0,"isAD" : false,"updateTime" : 1556640000000},"highlight" : {"name" : ["<em>华</em><em>为</em>(HUAWEI)<em>华</em><em>为</em>P20手机 极光色 全网通(6GB+64GB)(<em>华</em><em>为</em>直供,送礼包)"]}},
@Test
void HighlightQuery() throws IOException {// 1.创建RequestSearchRequest request = new SearchRequest("items");// 2.组织请求参数// 2.1.query条件request.source().query(QueryBuilders.matchQuery("name", "脱脂牛奶"));// 2.2.高亮条件request.source().highlighter(SearchSourceBuilder.highlight().field("name").preTags("<em>").postTags("</em>"));// 3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.解析响应handleResponse1(response);
}
private void handleResponse1(SearchResponse response) {SearchHits searchHits = response.getHits();// 1.获取总条数long total = searchHits.getTotalHits().value;System.out.println("共搜索到" + total + "条数据");// 2.遍历结果数组SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {// 3.得到_source,也就是原始json文档String source = hit.getSourceAsString();// 4.反序列化ItemDoc item = JSONUtil.toBean(source, ItemDoc.class);// 5.获取高亮结果Map<String, HighlightField> hfs = hit.getHighlightFields();if (CollUtils.isNotEmpty(hfs)) {// 5.1.有高亮结果,获取name的高亮结果HighlightField hf = hfs.get("name");if (hf != null) {// 5.2.获取第一个高亮结果片段,就是商品名称的高亮值String hfName = hf.getFragments()[0].string();item.setName(hfName);}}System.out.println(item);}
}
地理坐标查询
  • 用于搜索地理位置,搜索方式很多,例如:
    • geo_bounding_box:按矩形搜索
    • geo_distance:按点和半径搜索
  • …略
聚合函数
@Test
void testAgg() throws IOException {// 1.创建RequestSearchRequest 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.获取桶内keyString brand = bucket.getKeyAsString();System.out.print("brand = " + brand);long count = bucket.getDocCount();System.out.println("; count = " + count);}
}

相关文章:

Elasticseach RestClient Api

Elasticsearch RestclientApi基础用法 查询 索引库 初始化 添加依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>创建链接 package com…...

【网络安全学习】漏洞扫描:-04- ZAP漏洞扫描工具

**ZAP(Zed Attack Proxy)**是一款由OWASP组织开发的免费且开源的安全测试工具。 ZAP支持认证、AJAX爬取、自动化扫描、强制浏览和动态SSL证书等功能。 1️⃣ 安装zap工具 现在的kali版本不一定会预装zap&#xff0c;我们可以自行安装&#xff0c;安装也十分简单。 apt-get …...

fffdddd

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;entity GJL isport(clk, reset: in std_logic;btn_green, btn_red: in std_logic; -- 新增控制按键r1, r2, y1, y2, g1, g2: out std_logic;ledag: out std_logic_…...

SpringSecurity实战入门——授权

权限系统的作用 例如一个学校图书馆的管理系统,如果是普通学生登录就能看到借书还书相关的功能,不可能让他看到并且去使用添加书籍信息,删除书籍信息等功能。但是如果是一个图书馆管理员的账号登录了,应该就能看到并使用添加书籍信息,删除书籍信息等功能。 总结起来就是…...

Linux 网络请求工具:curl

文章目录 Linux 网络请求&#xff1a;curl1. 安装2. 常规用法3. 传输速率4. FTP5. 代理 Linux 网络请求&#xff1a;curl 1. 安装 若系统没有 curl 命令&#xff0c;可以直接通过 yum 或者 dnf 安装&#xff1a; yum -y install curl # 查看版本&#xff0c;确认安装结果 cu…...

leetcode 二分查找·系统掌握 寻找旋转排序数组中的最小值II

题目&#xff1a; 题解&#xff1a; 本题比普通的寻找旋转排序数组中的最小值多了一个数组中的元素可以重复这一点。 这会时原来的思路出现一个漏洞&#xff08;大家感兴趣可以看看我做普通版寻找旋转排序数组最小值的思路&#xff09;&#xff0c;就是旋转后的数组中的第二个…...

Flink 容错

Apache Flink 的容错机制是确保数据流应用程序在出现故障时能够恢复一致状态的关键机制。这一机制主要通过创建分布式数据流和操作符状态的一致快照来实现&#xff0c;这些快照被称为检查点&#xff08;Checkpoint&#xff09;。以下是 Flink 容错机制的主要特点和关键点&#…...

OpenAI策略:指令层级系统让大模型免于恶意攻击

现代的大模型&#xff08;LLMs&#xff09;不再仅仅是简单的自动完成系统&#xff0c;它们有潜力赋能各种代理应用&#xff0c;如网页代理、电子邮件秘书、虚拟助手等。然而&#xff0c;这些应用广泛部署的一个主要风险是敌手可能诱使模型执行不安全或灾难性的行动&#xff0c;…...

芝麻清单助力提升学习工作效率 专注时间完成有效的待办事项

芝麻清单助力提升学习&工作效率 专注时间完成有效的工作。今天我们给大家带来一个专注清单&#xff0c;一个更高效的学习和工作的方法&#xff01; 我们都知道&#xff0c;专注做一个事情&#xff0c;会有效的提升效率&#xff0c;让事情更高效的完成。如果是学习的话&…...

Docker 容器操作命令

文章目录 前言1. 创建并运行容器2. 列出容器3. 停止容器4. 启动已停止的容器5. 重启容器6. 进入容器7. 删除容器8. 查看容器日志9. 导出和导入容器10. 管理网络11. 数据卷操作12. 设置容器自启动 前言 Docker 容器操作是 Docker 使用过程中非常重要的一部分。以下是一些常见的…...

华为配置创建vlan及划接口,trunk干道,DHCP池塘配置

1、创建 vlan [SWA]vlan 10 [SWA-vlan10]quit [SWA]vlan batch2to3510 批量创建vlan2-3&#xff0c;5.10 2、 接口划入 vlan 单个接口修改接口模式为 access [SWA]interface GigabitEthernet 0/0/5 [SWA-GigabitEthernet0/0/5]port link-type access 批修改为 access [H…...

vue3 computed与watch,watchEffect比较

相同点 都是要根据一个或多个响应式数据进行监听 不同点 computed 如要return回来一个新的响应式值&#xff0c;且这个值不允许直接修改&#xff0c;想要修改的话可以设置set函数&#xff0c;在函数里面去修改所依赖的响应式数据&#xff0c;然后计算属性值会基于其响应式依…...

论文:R语言数据分析之机器学习论文

欢迎大家关注全网生信学习者系列&#xff1a; WX公zhong号&#xff1a;生信学习者Xiao hong书&#xff1a;生信学习者知hu&#xff1a;生信学习者CDSN&#xff1a;生信学习者2 一、研究背景 全球范围内&#xff0c;乳腺癌是导致癌症发病率和死亡率的主要疾病之一。根据2018年…...

【C++】STL中优先级队列的使用与模拟实现

前言&#xff1a;在前面我们学习了栈和队列的使用与模拟实现&#xff0c;今天我们来进一步的学习优先级队列使用与模拟实现 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff23;学习 &#x1f448; &#x1f4af;代码仓库:卫…...

C#开发-集合使用和技巧(二)Lambda 表达式介绍和应用

C#开发-集合使用和技巧 Lambda 表达式介绍和应用 C#开发-集合使用和技巧介绍简单的示例&#xff1a;集合查询示例&#xff1a; 1. 基本语法从主体语句上区分&#xff1a;1. 主体为单一表达式2. 主体是代码块&#xff08;多个表达式语句&#xff09; 从参数上区分1. 带输入参数的…...

Qt底层原理:深入解析QWidget的绘制技术细节(2)

&#xff08;本文续上一篇《Qt底层原理&#xff1a;深入解析QWidget的绘制技术细节(1)》&#xff09; QWidget绘制体系为什么这么设计【重点】 在传统的C图形界面框架中&#xff0c;例如DUILib等&#xff0c;控件的绘制逻辑往往直接在控件的类的内部&#xff0c;例如PushButt…...

【Gradio】表格数据科学与图表-连接到数据库

简介 本指南解释了如何使用 Gradio 将您的应用程序连接到数据库。我们将连接到托管在 AWS 上的 PostgreSQL 数据库&#xff0c;但 gradio 对您连接到的数据库类型及其托管位置完全不可知。因此&#xff0c;只要您能够编写 Python 代码来连接到您的数据&#xff0c;您就可以使用…...

艾多美用“艾”为生命加油,献血活动回顾

用艾为生命加油 6月10日~16日&#xff0c;艾多美中国开启献血周活动&#xff0c;已经陆续收到来自烟台总部、山东、广东、河南、四川、重庆、贵阳&#xff0c;乌鲁木齐&#xff0c;吉林&#xff0c;等地区的艾多美员工、会员、经销商发来的爱心助力&#xff0c;截止到目前&…...

人工智能在气象预报领域的崛起:GraphCast引领新纪元

最近&#xff0c;谷歌推出的天气预测大模型GraphCast在全球范围内引起了广泛关注&#xff0c;其卓越的表现不仅刷新了人们对AI能力的认知&#xff0c;更预示着传统天气预报工作模式的深刻变革。 GraphCast是一款基于机器学习技术的天气预测工具&#xff0c;它通过深度学习和大数…...

http和https的区别在哪

HTTP&#xff08;超文本传输协议&#xff09;和HTTPS&#xff08;超文本传输安全协议&#xff09;之间存在几个关键区别主要涉及安全性、端口、成本、加密方式、搜索引擎优化&#xff08;SEO&#xff09;、身份验证等方面 1、安全性&#xff1a;HTTP&#xff08;超文本传输协议…...

windows10远程桌面端口,Windows 10远程桌面端口修改的两个方法

在Windows 10系统中&#xff0c;远程桌面功能允许用户通过网络从一台计算机远程访问和控制另一台计算机。默认情况下&#xff0c;远程桌面服务使用的端口是3389。然而&#xff0c;出于安全考虑&#xff0c;许多管理员和用户希望修改这一默认端口。本指南将详细介绍如何在Window…...

力扣1504.统计全1子矩形

力扣1504.统计全1子矩形 开一个二维数组存每个点从它本身开始向左有多少连续的1 遍历矩形右下角(i,j) 再遍历行k in i每一行的矩形数量 minx min(minx,left(k,j)) class Solution {public:int numSubmat(vector<vector<int>>& mat) {int n mat.size();int…...

vue3高德地图组件化,解决复用地图组件时渲染失败问题

思路&#xff1a;多个页面都需要调用地图&#xff0c;将地图封装成一个组件进行复用&#xff0c;发现调用时只有第一次渲染成功了。 解决&#xff1a;相同 id 的地图渲染只能有一次&#xff0c;如果多个复用地图的页面不需要同时渲染&#xff0c;使用 v-if 来控制&#xff1b;…...

Langchain 如何工作

How does LangChain work? LangChain是如何工作的? Let’s consider our initial example where we upload the US Constitution PDF and pose questions to it. In this scenario, LangChain compiles the data from the PDF and organizes it. 让我们考虑我们最初的例子…...

【数据结构】顺序表实操——通讯录项目

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…...

C++继承与多态—多重继承的那些坑该怎么填

课程总目录 文章目录 一、虚基类和虚继承二、菱形继承的问题 一、虚基类和虚继承 虚基类&#xff1a;被虚继承的类&#xff0c;就称为虚基类 virtual作用&#xff1a; virtual修饰成员方法是虚函数可以修饰继承方式&#xff0c;是虚继承&#xff0c;被虚继承的类就称为虚基类…...

论文阅读:基于谱分析的全新早停策略

来自JMLR的一篇论文&#xff0c;https://www.jmlr.org/papers/volume24/21-1441/21-1441.pdf 这篇文章试图通过分析模型权重矩阵的频谱来解释模型&#xff0c;并在此基础上提出了一种用于早停的频谱标准。 1&#xff0c;分类难度对权重矩阵谱的影响 1.1 相关研究 在最近针对…...

1.接口测试-postman学习

目录 1.接口相关概念2.接口测试流程3.postman基本使用-创建请求&#xff08;1&#xff09;环境&#xff08;2&#xff09;新建项目集合Collections&#xff08;3&#xff09;新建collection&#xff08;4&#xff09;新建模块&#xff08;5&#xff09;构建请求请求URLheader设…...

2024年码蹄杯本科院校赛道初赛(省赛)

赛时所写题&#xff0c;简单写一下思路&#xff0c;qwq 第一题&#xff1a; 输出严格次小值&#xff0c; //#pragma GCC optimize(2)#include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <queue> #incl…...

PHP蜜语翻译器在线文字转码解码源码

源码介绍 PHP蜜语翻译器在线文字转码解码源码 文字加密通话、一键转换、蜜语密码 无需数据库,可以将文字、字母、数字、代码、表情、标点符号等内容转换成新的文字形式&#xff0c;通过简单的文字以不同的排列顺序来表达不同的内容&#xff01;支持在线加密解密 有多种加密展示…...

安卓浏览器区分启动、打开、分享

搞了几个钟头&#xff0c;终于全兼容了&#xff0c;分享有2种类型&#xff01; void getDataFromIntent(Intent intent) {if (intent.getAction().equals(Intent.ACTION_VIEW)) {urln intent.getDataString();if (urln ! null) {if (urln.contains("\n"))urln url…...

C/C++ 数组负数下标

一 概述 在 C 中&#xff0c;数组是一块连续的内存空间&#xff0c;数组的下标通常用来定位这段内存中的特定元素。下标通常从 0 开始&#xff0c;最大到数组长度减 1。例如&#xff0c;一个有 10 个元素的数组&#xff0c;其有效下标范围是从 0 到 9。 当你尝试使用负数下标来…...

钓鱼网站开发原理(社会工程学)

钓鱼网站开发原理&#xff08;社会工程学&#xff09; 一、课程简介1、课程大纲2、课程目标3、知识储备 二、钓鱼网站简介1、什么是钓鱼网站2、开发&原理 三、PHP环境搭建1、简介2、自动安装MySQL/apache/PHP3、安装navicat 四、PDO表单入库案例1、语法2、显示登录表单3、入…...

如何优雅地使用 console.log 打印数组或对象

一、背景 使用 console.log 在控制台中打印数组或者对象时&#xff0c;很多时候它们的字段都是默认关闭的&#xff0c;需要手动一个个的点开&#xff0c;非常不直观且麻烦。 二、解决方案 使用 JSON.stringify() 的第三个参数 我们来看一下官方对于 JSON.stringify 的介绍 三、…...

模式分解的概念(下)-无损连接分解的与保持函数依赖分解的定义和判断、损失分解

一、无损连接分解 1、定义 2、检验一个分解是否是无损连接分解的算法 输入与输出 输入&#xff1a; 关系模式R&#xff08;U&#xff0c;F&#xff09;&#xff0c;F是最小函数依赖集 R上的一个分解 输出&#xff1a; 判断分解是否为无损连接分解 &#xff08;1&#x…...

vue3父组件获取子组件的实例对象

一&#xff0c;ref 在父组件的模板里&#xff0c;对子组件的标签定义ref属性&#xff0c;并且设置属性值&#xff0c;在方法里获取ref()获取实例对象。 父组件&#xff1a; <template><div ><div>我是父组件</div><<SonCom ref"sonComRe…...

主流框架选择:React、Angular、Vue的详细比较

目前前端小伙伴经常使用三种广泛使用的开发框架&#xff1a;React、Angular、Vue - 来设计网站 Reactjs&#xff1a;效率和多功能性而闻名 Angularjs&#xff1a;创建复杂的应用程序提供了完整的解决方案&#xff0c;紧凑且易于使用的框架 Vuejs&#xff1a;注重灵活性和可重用…...

交易者的意义是什么?

按照阿德勒的说法&#xff1a;人生的意义就是为社会创造价值&#xff0c;推动整个人类社会的发展进步。 我认同且秉持这种观点。 而在交易中&#xff0c;你是否直接或者间接为社会做贡献了呢&#xff1f;这个还真不好说。 但是做为职业交易者&#xff0c;你的存在价值&#…...

io_uring

转&#xff1a;[译] Linux 异步 I_O 框架 io_uring&#xff1a;基本原理、程序示例与性能压测&#xff08;2020&#xff09; 新一代异步IO框架 io_uring &#xff5c; 得物技术 干翻 nio &#xff0c;王炸 io_uring 来了 &#xff01;&#xff01;&#xff08;图解史上最全&a…...

构建高并发Web应用:基于Gunicorn、Flask和Docker的部署指南

目录 一 理解基础组件 什么是Flask? 什么是Gunicorn? 什么是Docker? 二 环境准备 三 构建Flask应用 创建项目结构 编写Flask应用 app/views.py 四 使用Gunicorn部署Flask应用 配置Gunicorn Gunicorn配置文件 五 使用Docker进行容器化部署 编写Dockerfile 构建…...

【Ruby简单脚本02】双色球系统

# frozen_string_literal: true require date # 生成中奖号码的工具 # 红球 1-32 篮球 1-15 def create_num nums [] 6.times do while true num rand(1..32) unless nums.include?(num) nums << num break end end end blue rand(1..15) nums…...

Netty ByteBuf 使用详解

文章目录 1.概述2. ByteBuf 分类3. 代码实例3.1 常用方法3.1.1 创建ByteBuf3.1.2 写入字节3.1.3 扩容3.1.2.1 扩容实例3.1.2.2 扩容计算新容量代码 3.1.4 读取字节3.1.5 标记回退3.1.6 slice3.1.7 duplicate3.1.8 CompositeByteBuf3.1.9 retain & release3.1.9.1 retain &a…...

怎样去掉卷子上的答案并打印

当面对试卷答案的问题时&#xff0c;一个高效而简单的方法是利用图片编辑软件中的“消除笔”功能。这种方法要求我们首先将试卷拍摄成照片&#xff0c;然后利用该功能轻松擦除答案。尽管这一方法可能需要些许时间和耐心&#xff0c;但它确实为我们提供了一个可行的解决途径。 然…...

海思SS928/SD3403开发笔记1——使用串口调试开发板

该板子使用串口可以调试&#xff0c;下面是win11 调试 该板子步骤 1、给板子接入鼠标、键盘、usb转串口 2、下载SecureCRT&#xff0c;并科学使用 下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/11dIkZVstvHQUhE8uS1YO0Q 提取码&#xff1a;vinv 3、安装c…...

JSON数据操作艺术

在现代Web开发和数据交换场景中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&#xff0c;扮演着至关重要的角色。它以易于阅读的文本形式存储和传输数据对象&#xff0c;而这些对象的核心便是由属性名&#xff08;键&…...

如何验证Rust中的字符串变量在超出作用域时自动释放内存?

讲动人的故事,写懂人的代码 在公司内部的Rust培训课上,讲师贾克强比较了 Rust、Java 和 C++ 三种编程语言在变量越过作用域时自动释放堆内存的不同特性。 Rust 通过所有权系统和借用检查,实现了内存安全和自动管理,从而避免了大部分内存泄漏。Rust 自动管理标准库中数据类…...

55.Python pip install 安装失败的一个情况Requirement already satisfied

1.问题 以前使用Pycharm 社区版开发的一个项目&#xff0c;今天使用PyCharm 专业版打开&#xff0c;原项目的虚拟环境从venv更换为.venv&#xff0c;然后重新安装插件。安装时&#xff0c;提示Requirement already satisfied: qt_material in c:\tools\python37\lib\site-packa…...

Axios进阶

目录 axios实例 axios请求配置 拦截器 请求拦截器 响应拦截器 取消请求 axios不仅仅是简单的用基础请求用法的形式向服务器请求数据&#xff0c;一旦请求的端口与次数变多之后&#xff0c;简单的请求用法会有些许麻烦。所以&#xff0c;axios允许我们进行创建axios实例、ax…...

C++ 丑数

描述 把只包含质因子2、3和5的数称作丑数&#xff08;Ugly Number&#xff09;。例如6、8都是丑数&#xff0c;但14不是&#xff0c;因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第 n个丑数。 数据范围&#xff1a;0≤&#x1d45b;≤20000≤n≤…...

小山菌_代码随想录算法训练营第三十天|122.买卖股票的最佳时机II、55. 跳跃游戏 、45.跳跃游戏II、1005.K次取反后最大化的数组和

122.买卖股票的最佳时机II 文档讲解&#xff1a;代码随想录.买卖股票的最佳时机II 视频讲解&#xff1a;贪心算法也能解决股票问题&#xff01;LeetCode&#xff1a;122.买卖股票最佳时机II 状态&#xff1a;已完成 代码实现 class Solution { public:int maxProfit(vector<…...