? ? 在Spring boot中主要有Java REST Client、spring-data-elasticsearch兩種方式,這里建議使用Elasticsearch官方提供的Java High Level REST Client來集成。
一:導(dǎo)入依賴:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.10.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.10.2</version>
</dependency>
創(chuàng)建es映射
PUT user_index
{
"settings":{
"number_of_shards": "3",
"number_of_replicas": "0"
},
"mappings": {
"properties":{
"age" : {
"type" : "short"
},
"createTime" : {
"type" : "long"
},
"id" : {
"type" : "integer"
},
"updateTime" : {
"type" : "long"
},
"userName" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword"
}
}
}
}
}
}
二:初始化客戶端
1,添加配置文件添加連接信息
elasticsearch:
host: 127.0.0.1:9200
port: 9200
connTimeout: 3000
socketTimeout: 5000
connectionRequestTimeout: 1000
username: elastic
password: 123456
2,添加ES配置類
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
/**
* @date 2022/7/15
**/
@Configuration
public class ElasticsearchConfiguration {
@Value("${elasticsearch.host}")
private String host;
@Value("${elasticsearch.port}")
private Integer port;
@Value("${elasticsearch.connTimeout}")
private Integer connTimeout;
@Value("${elasticsearch.socketTimeout}")
private Integer socketTimeout;
@Value("${elasticsearch.connectionRequestTimeout}")
private Integer connectionRequestTimeout;
@Value("${elasticsearch.username}")
private String username;
@Value("${elasticsearch.password}")
private String password;
@Bean(destroyMethod = "close", name = "client")
public RestHighLevelClient initRestClient() {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
RestClientBuilder builder = RestClient.builder(toHttpHost())
.setRequestConfigCallback(requestConfigBuilder ->
requestConfigBuilder.setConnectTimeout(connTimeout)
.setSocketTimeout(socketTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout))
.setHttpClientConfigCallback(h -> h.setDefaultCredentialsProvider(credentialsProvider));
return new RestHighLevelClient(builder);
}
/**
* 解析配置的字符串,轉(zhuǎn)為HttpHost對象數(shù)組
*/
private HttpHost[] toHttpHost() {
if (!StringUtils.hasLength(host)) {
throw new RuntimeException("invalid elasticsearch configuration");
}
String[] hostArray = host.split(",");
HttpHost[] httpHosts = new HttpHost[hostArray.length];
HttpHost httpHost;
for (int i = 0; i < hostArray.length; i++) {
String[] strings = hostArray[i].split(":");
httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
httpHosts[i] = httpHost;
}
return httpHosts;
}
}
三,springboot api封裝
@Component
public class EsUtil {
@Resource
private RestHighLevelClient restHighLevelClient;
/**
* 創(chuàng)建索引
*/
@SneakyThrows
public Boolean createIndex(String indexName) {
CreateIndexRequest request = new CreateIndexRequest(indexName);
// request.settings() 可以設(shè)置分片規(guī)則
// request.mapping() 可以設(shè)置映射字段
CreateIndexResponse indexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
return indexResponse.isAcknowledged();
}
/**
* 查詢索引 * 查詢?nèi)? */
@SneakyThrows
public List<String> searchIndex(String indexName) {
GetIndexRequest request = new GetIndexRequest(indexName);
boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
if (!exists) {
return Lists.newArrayList();
}
GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(request, RequestOptions.DEFAULT);
return Lists.newArrayList(getIndexResponse.getIndices());
}
/**
* 刪除索引
*/
@SneakyThrows
public Boolean deleteIndex(String indexName) {
GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
if (!exists) {
return false;
}
DeleteIndexRequest request = new DeleteIndexRequest(indexName);
AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
return response.isAcknowledged();
}
/**
* 文檔數(shù)據(jù)插入(插入前會自動生成index)
* source() 支持json map 鍵值對等形式
*/
@SneakyThrows
public String insert(String indexName, String id, String jsonStr) {
IndexRequest indexRequest = new IndexRequest(indexName);
// 不設(shè)置id 會自動使用es默認的
if (StrUtil.isNotBlank(id)) {
indexRequest.id(id);
}
indexRequest.source(jsonStr, XContentType.JSON);
IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
return indexResponse.getId();
}
/**
* 批量插入數(shù)據(jù)
* map {id, json}
*/
@SneakyThrows
public BulkResponse insertBatch(String indexName, Map<String, String> valueMap) {
BulkRequest bulkRequest = new BulkRequest();
Set<String> keySet = valueMap.keySet();
for (String id : keySet) {
IndexRequest request = new IndexRequest(indexName).id(id).source(valueMap.get(id), XContentType.JSON);
bulkRequest.add(request);
}
return restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
}
/**
* 更新- es有則更新,無則寫入
* 可以接受 String、Map、XContentBuilder 或 Object 鍵對
*/
@SneakyThrows
public String update(String indexName, String id, String jsonStr) {
String searchById = searchById(indexName, id);
if (StrUtil.isBlank(searchById)) {
return null;
}
UpdateRequest updateRequest = new UpdateRequest(indexName, id).doc(jsonStr, XContentType.JSON);
UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
return update.getId();
}
/**
* 根據(jù)id進行刪除
*/
@SneakyThrows
public String delete(String indexName, String id) {
DeleteRequest deleteRequest = new DeleteRequest(indexName, id);
DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
return delete.getId();
}
/**
* 根據(jù)id進行刪除
*/
@SneakyThrows
public List<String> deleteBatch(String indexName, List<String> ids) {
List<String> deleteList = Lists.newArrayList();
if (CollectionUtil.isEmpty(ids)) {
return deleteList;
}
for (String id : ids) {
DeleteRequest deleteRequest = new DeleteRequest(indexName, id);
deleteList.add(restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT).getId());
}
return deleteList;
}
/**
* 根據(jù)id進行查詢
*/
@SneakyThrows
public String searchById(String indexName, String id) {
GetRequest getRequest = new GetRequest(indexName, id);
GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
return getResponse.getSourceAsString();
}
/**
* 根據(jù)QueryBuilder來查詢?nèi)康臈l數(shù)
*/
@SneakyThrows
public Long findTotal(String indexName, QueryBuilder builder) {
SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.source().query(builder);
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
return response.getHits().getTotalHits().value;
}
/**
* 1, id查詢: QueryBuilders.idsQuery().ids(id)
* 精確查詢 QueryBuilders.termQuery("userName.keyword", "王五") .keyword 值是中文時需要,非中文時不需要
* 范圍查詢:QueryBuilders.rangeQuery().form().to().includeLower(false).includeUpper(false) 默認是true包含頭尾,設(shè)置false去掉頭尾
* 匹配所有:QueryBuilders.matchAllQuery()
* 模糊查詢:QueryBuilders.fuzzyQuery()
* 全文檢索,會進行分詞,多個字段檢索:QueryBuilders.multiMatchQuery("kimchy", "name", "description") 查詢name或description包含kimchy
* 全文檢索,會進行分詞,單字段檢索:QueryBuilders.matchQuery(name", "kimchy") 查詢name包含kimchy
* 通配符查詢, 支持*,匹配任何字符序列, 包括空,避免* 開始 QueryBuilders.wildcardQuery("user", "ki*hy")
* 跨度查詢:QueryBuilders.span………
* 2,組合查詢:BoolQueryBuilder must:and mustNot:not should:or in:termsQuery傳list
* QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("name", Lists.newArrayList())).mustNot(QueryBuilders.……);
* 過濾器查詢:在原本查詢結(jié)果的基礎(chǔ)上對數(shù)據(jù)進行篩選,不會計算分值,所以效率比must更高
* QueryBuilders.boolQuery().filter(QueryBuilders.termQuery("userName", "王五"))
* 3, 查詢部分字段: SearchSourceBuilder().fetchSource(new String[]{"userName", "age"}, new String[]{}) 查詢userName和age字段
* 4, 權(quán)重計算,權(quán)重越高月靠前: 給name精確查詢提高權(quán)重為2 QueryBuilders.termQuery("name", "kimchy").boost(2.0f)
* 高于設(shè)定分數(shù), 不計算相關(guān)性查詢: QueryBuilders.constantScoreQuery(QueryBuilders.termQuery("name", "kimchy")).boost(2.0f);
* 5,Nested&Join父子類型:得檢索效率慢,不建議在ES做Join操作
* 父子查詢:QueryBuilders.hasChildQuery("tweet", QueryBuilders.termQuery("user", "kimchy")).scoreMode("max")
* 嵌套查詢, 內(nèi)嵌文檔查詢 QueryBuilders.nestedQuery("location", QueryBuilders.boolQuery()
* .must(QueryBuilders.matchQuery("location.lat", 0.962590433140581))
* .must(QueryBuilders.rangeQuery("location.lon").lt(36.0000).gt(0.000))).scoreMode("total")
* 6, 排序:在查詢的結(jié)果上進行二次排序,date、float 等類型添加排序,text類型的字段不允許排序 SearchSourceBuilder.sort()
*/
@SneakyThrows
public List<Map<String, Object>> findAll(String indexName, QueryBuilder builder) {
// 設(shè)置源字段過慮,第一個參數(shù)結(jié)果集包括哪些字段,第二個參數(shù)表示結(jié)果集不包括哪些字段
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
.query(builder)
.fetchSource(new String[]{"userName", "age"}, new String[]{});
SearchRequest request = new SearchRequest(indexName).source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
return handleResponse(response, 0, 0).getRecords();
}
/**
* 1,from-size淺分頁適合數(shù)據(jù)量不大的情況(官網(wǎng)推薦是數(shù)據(jù)少于10000條),可以跳碼進行查詢
* 2,scroll 是一種滾屏形式的分頁檢索,scroll查詢是很耗性能的方式,不建議在實時查詢中運用
*/
@SneakyThrows
public P<Map<String, Object>> fromSizePage(String indexName, QueryBuilder queryBuilder, BasePageForm basePageForm) {
int from = basePageForm.getPageSize() * (basePageForm.getPageNum() - 1);
// 構(gòu)建分頁搜尋器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(queryBuilder)
.from(from)
.size(basePageForm.getPageSize());
if (StrUtil.isNotBlank(basePageForm.getOrderBy())) {
sourceBuilder.sort(basePageForm.getOrderBy(), basePageForm.getOrderType() ? SortOrder.ASC : SortOrder.DESC);
}
SearchRequest request = new SearchRequest(indexName).source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
return handleResponse(response, basePageForm.getPageNum(), basePageForm.getPageSize());
}
/**
* 分頁返回值處理
*/
@SneakyThrows
private P<Map<String, Object>> handleResponse(SearchResponse response, int pageNum, int pageSize) {
SearchHit[] hits = response.getHits().getHits();
List<Map<String, Object>> result = Arrays.stream(hits).map(h -> {
Map<String, Object> sourceAsMap = h.getSourceAsMap();
sourceAsMap.put("id", h.getId());
return sourceAsMap;
}).collect(Collectors.toList());
return new P<>(result, response.getHits().getTotalHits().value, pageSize, pageNum);
}
/**
* search_after 適用于深度分頁+ 排序,分頁是根據(jù)上一頁最后一條數(shù)據(jù)來定位下一頁的位置,所以無法跳頁請求,性能最好
*/
@SneakyThrows
public P<Map<String, Object>> searchAfterPage(String indexName, QueryBuilder queryBuilder, BasePageForm basePageForm) {
// 構(gòu)建分頁搜尋器
// searchAfter需要將from設(shè)置為0或-1,當(dāng)然也可以不寫
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(queryBuilder)
.from(0)
.size(basePageForm.getPageSize());
if (StrUtil.isNotBlank(basePageForm.getOrderBy())) {
sourceBuilder.sort(basePageForm.getOrderBy(), basePageForm.getOrderType() ? SortOrder.ASC : SortOrder.DESC);
}
if (null != basePageForm.getSortCursor() && basePageForm.getSortCursor().length > 0) {
sourceBuilder.searchAfter(basePageForm.getSortCursor());
}
SearchRequest request = new SearchRequest(indexName).source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
Object[] sortCursor = hits[hits.length - 1].getSortValues();
P<Map<String, Object>> page = handleResponse(response, basePageForm.getPageNum(), basePageForm.getPageSize());
page.setSortCursor(sortCursor);
return page;
}
/**
* moreLikeThisQuery: 實現(xiàn)基于內(nèi)容推薦, 支持實現(xiàn)一句話相似文章查詢
* percent_terms_to_match:匹配項(term)的百分比,默認是0.3
* min_term_freq:一篇文檔中一個詞語至少出現(xiàn)次數(shù),小于這個值的詞將被忽略,默認是2
* max_query_terms:一條查詢語句中允許最多查詢詞語的個數(shù),默認是25
* stop_words:設(shè)置停止詞,匹配時會忽略停止詞
* min_doc_freq:一個詞語最少在多少篇文檔中出現(xiàn),小于這個值的詞會將被忽略,默認是無限制
* max_doc_freq:一個詞語最多在多少篇文檔中出現(xiàn),大于這個值的詞會將被忽略,默認是無限制
* min_word_len:最小的詞語長度,默認是0
* max_word_len:最多的詞語長度,默認無限制
* boost_terms:設(shè)置詞語權(quán)重,默認是1
* boost:設(shè)置查詢權(quán)重,默認是1
* analyzer:設(shè)置使用的分詞器,默認是使用該字段指定的分詞器
*/
public List<Map<String, Object>> moreLikeThisQuery(String indexName) {
QueryBuilder queryBuilder = QueryBuilders.moreLikeThisQuery(new String[]{"王"})
.minTermFreq(1).maxQueryTerms(3);
return findAll(indexName, queryBuilder);
}
/**
* 聚合查詢: todo 字段類型是text就不支持聚合排序
* 桶(bucket): 滿足特定條件的文檔的集合 GROUP BY userName
* 指標(biāo)(metric): 對桶內(nèi)的文檔進行聚合分析的操作 COUNT(userName)
* select age, createTime, SUM(age), AVG(age),MIN(age),COUNT(age) from user_index GROUP BY age, createTime
*/
@SneakyThrows
public List<Object> aggregateQuery(String indexName, List<String> fieldList, TermsAggregationBuilder aggregation) {
if (CollectionUtil.isEmpty(fieldList)) {
return Lists.newArrayList();
}
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().aggregation(aggregation);
SearchRequest request = new SearchRequest(indexName).source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
return handleResult(response);
}
/**
* 對聚合結(jié)果進行封裝
*/
private static List<Object> handleResult(SearchResponse agg){
Map<String, Aggregation> aggregations = agg.getAggregations().asMap();
List<Object> objects = Lists.newArrayList();
// 第一層分組統(tǒng)計
aggregations.forEach((k,v) -> {
Map<String, Object> group = Maps.newHashMap();
parseAggs(k, v, group, objects);
});
return objects;
}
/**
* 解析聚合結(jié)果
*/
private static void parseAggs(String key, Aggregation value, Map<String, Object> group, List<Object> objects){
if (value instanceof Terms){
for (Terms.Bucket bucket:((Terms) value).getBuckets() ){
Set<Map.Entry<String, Aggregation>> entries = bucket.getAggregations().asMap().entrySet();
group.put(key, bucket.getKeyAsString());
for (Map.Entry<String, Aggregation> entry : entries) {
if (entry.getValue() instanceof Terms){
parseAggs(entry.getKey(), entry.getValue(), group, objects);
} else {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
bucket.getAggregations().asMap().forEach((k2, v2) -> map.put(k2, getValue(v2)));
map.putAll(group);
objects.add(map);
break;
}
}
}
}
}
/**
* 取值
*/
private static String getValue(Aggregation agg) {
switch (agg.getType()) {
case "avg":
return String.valueOf(((Avg) agg).getValue());
case "sum":
return String.valueOf(((Sum) agg).getValue());
case "value_count":
return String.valueOf(((ValueCount) agg).getValue());
case "min":
return String.valueOf(((Min) agg).getValue());
case "max":
return String.valueOf(((Max) agg).getValue());
case "cardinality":
return String.valueOf(((Cardinality) agg).getValue());
default:
return String.valueOf(agg);
}
}
基礎(chǔ)的分頁參數(shù)文章來源:http://www.zghlxwxcb.cn/news/detail-514559.html
@Data
@ApiModel("基礎(chǔ)分頁信息 BasePageForm")
public class BasePageForm {
@ApiModelProperty(value = "頁條數(shù)", example = "20")
private int pageSize = 20;
@ApiModelProperty(value = "第幾頁", example = "1")
private int pageNum = 1;
@ApiModelProperty(value = "排序字段: 可選: 不同列表排序不同需再協(xié)商", example = "")
private String orderBy;
@ApiModelProperty(value = "排序規(guī)則 true升序 false降序")
private Boolean orderType = false;
@ApiModelProperty("排序游標(biāo)")
private Object[] sortCursor;
@ApiModelProperty("查詢所有: 默認查詢今日及所有未審核單子")
private boolean isAll = false;
}
封裝的分頁返回對象文章來源地址http://www.zghlxwxcb.cn/news/detail-514559.html
@Data
@ApiModel("分頁查詢: P")
public class P<T> {
@ApiModelProperty("當(dāng)前頁數(shù)據(jù)")
private List<T> records;
@ApiModelProperty("總條數(shù)")
private long total;
@ApiModelProperty("每頁條數(shù)")
private long size;
@ApiModelProperty("第幾頁")
private long current;
@ApiModelProperty("sortCursor 游標(biāo)")
private Object[] sortCursor;
public P(List<T> records, long total, long size, long current) {
this.records = records;
this.total = total;
this.size = size;
this.current = current;
}
public P(List<T> records, Page page) {
this.records = records;
this.total = page.getTotal();
this.size = page.getSize();
this.current = page.getCurrent();
}
public static P of(List records, Page page) {
return new P(records, page);
}
public static <T> P<T> of(Page<T> page) {
return new P<>(page.getRecords(), page);
}
}
四:測試
/**
* es官方文檔:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.10/java-rest-high-supported-apis.html
* @author Gordon
* @date 2022/7/15
**/
@Api(tags = "es基本用法測試")
@RequestMapping("/ceshi")
@RestController
@Slf4j
public class TestController {
private static String indexName = "user_index";
@Resource
private EsUtil esUtil;
@ApiOperation(value = "創(chuàng)建索引")
@GetMapping("/createIndex")
public Boolean create(@RequestParam("indexName") String indexName) {
return esUtil.createIndex(indexName);
}
@ApiOperation(value = "查詢索引 * 查詢?nèi)?)
@GetMapping("searchIndex")
public List<String> searchIndex(@RequestParam("indexName") String indexName) {
return esUtil.searchIndex(indexName);
}
@ApiOperation(value = "刪除索引")
@GetMapping("deleteIndex")
public Boolean deleteIndex(@RequestParam("indexName") String indexName) {
return esUtil.deleteIndex(indexName);
}
@ApiOperation(value = "插入文檔")
@GetMapping("insert")
public String insert(@RequestParam("id") String id) {
User user = new User().setUserName("張三").setAge(22).setCreateTime(System.currentTimeMillis());
return esUtil.insert(indexName, id, JSON.toJSONString(user));
}
@ApiOperation(value = "批量插入")
@GetMapping("insertBatch")
public BulkResponse insertBatch() {
Map<String, String> build = new ImmutableMap.Builder<String, String>()
.put("1", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis()).setUserName("張三").setAge(22)))
.put("2", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 10000).setUserName("王五").setAge(23)))
.put("3", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 20000).setUserName("張三").setAge(25)))
.put("4", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 30000).setUserName("王五").setAge(26)))
.put("5", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 40000).setUserName("張三").setAge(28)))
.put("6", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 50000).setUserName("王五").setAge(27)))
.put("7", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 60000).setUserName("張三").setAge(24)))
.put("8", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 70000).setUserName("王五").setAge(22)))
.put("9", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 80000).setUserName("張三").setAge(23)))
.put("10", JSON.toJSONString(new User().setCreateTime(System.currentTimeMillis() + 90000).setUserName("王五").setAge(23)))
.build();
return esUtil.insertBatch(indexName, build);
}
@ApiOperation(value = "文檔id 更新文檔")
@GetMapping("update")
public String update(@RequestParam("id") String id) {
User user = new User().setUserName("李五").setUpdateTime(System.currentTimeMillis());
return esUtil.update(indexName, id, JSON.toJSONString(user));
}
@ApiOperation(value = "批更新")
@GetMapping("updateBatch")
public BulkResponse updateBatch() {
Map<String, String> build = new ImmutableMap.Builder<String, String>()
.put("2", JSON.toJSONString(new User().setUserName("張四").setUpdateTime(System.currentTimeMillis())))
.put("3", JSON.toJSONString(new User().setUserName("張五").setUpdateTime(System.currentTimeMillis())))
.build();
return esUtil.insertBatch(indexName, build);
}
@ApiOperation(value = "文檔id 刪除文檔")
@GetMapping("delete")
public String delete(@RequestParam("id") String id) {
return esUtil.delete(indexName, id);
}
@ApiOperation(value = "批量刪除文檔")
@GetMapping("deleteBatch")
public List<String> deleteBatch(@RequestParam("ids") List<String> ids) {
return esUtil.deleteBatch(indexName, ids);
}
@ApiOperation(value = "文檔id 查詢文檔")
@GetMapping("searchById")
public String searchById(@RequestParam("id") String id) {
return esUtil.searchById(indexName, id);
}
@ApiOperation(value = "查詢?nèi)康臈l數(shù)")
@GetMapping("findTotal")
public Long findTotal() {
TermQueryBuilder queryBuilder = QueryBuilders.termQuery("userName.keyword", "王五");
return esUtil.findTotal(indexName, queryBuilder);
}
@ApiOperation(value = "組合QueryBuilder 進行查詢")
@GetMapping("findAll")
public List<Map<String, Object>> findAll() {
QueryBuilder queryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.fuzzyQuery("userName.keyword", "李四"));
return esUtil.findAll(indexName, queryBuilder);
}
@ApiOperation(value = "分頁查詢文檔")
@PostMapping("fromSizePage")
public P<Map<String, Object>> fromSizePage(@RequestBody BasePageForm basePageForm) {
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("userName.keyword", "王五");
return esUtil.fromSizePage(indexName, termQueryBuilder, basePageForm);
}
@ApiOperation(value = "分頁查詢文檔")
@PostMapping("searchAfterPage")
public P<Map<String, Object>> searchAfterPage(@RequestBody BasePageForm basePageForm) {
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("createTime")
.from("1660634673318").to("1660634713318");
return esUtil.searchAfterPage(indexName, rangeQueryBuilder, basePageForm);
}
@ApiOperation(value = "單字段聚合查詢")
@GetMapping("sinFieldsAggregateQuery")
public List<Object> sinFieldsAggregateQuery() {
// 需要分組的字段,可以隨意指定
List<String> fieldList = Lists.newArrayList("age");
TermsAggregationBuilder termsAge = AggregationBuilders.terms(fieldList.get(0)).field(fieldList.get(0))
.subAggregation(AggregationBuilders.avg("avg").field(fieldList.get(0)))
.subAggregation(AggregationBuilders.sum("sum").field(fieldList.get(0)))
.subAggregation(AggregationBuilders.min("min").field(fieldList.get(0)))
.subAggregation(AggregationBuilders.count("count").field(fieldList.get(0)))
.subAggregation(AggregationBuilders.cardinality("cardinality").field(fieldList.get(0)));
return esUtil.aggregateQuery(indexName, fieldList, termsAge);
}
@ApiOperation(value = "多字段聚合查詢")
@GetMapping("multipleFieldsAggregateQuery")
public List<Object> multipleFieldsAggregateQuery() {
// 需要分組的字段,可以隨意指定
List<String> fieldList = Lists.newArrayList("age", "createTime");
TermsAggregationBuilder termsAge = AggregationBuilders.terms(fieldList.get(0)).field(fieldList.get(0));
TermsAggregationBuilder termsCreateTime = AggregationBuilders.terms(fieldList.get(1)).field(fieldList.get(1))
.subAggregation(AggregationBuilders.avg("avg").field(fieldList.get(0)))
.subAggregation(AggregationBuilders.sum("sum").field(fieldList.get(0)))
.subAggregation(AggregationBuilders.min("min").field(fieldList.get(0)))
.subAggregation(AggregationBuilders.count("count").field(fieldList.get(0)))
.subAggregation(AggregationBuilders.cardinality("cardinality").field(fieldList.get(0)));
return esUtil.aggregateQuery(indexName, fieldList, termsAge.subAggregation(termsCreateTime));
}
}
?五:如何修改es字段類型,比如之前是text,現(xiàn)在要改成 keyword
創(chuàng)建新索引
PUT user_index1
{
"mappings" : {
"properties" : {
"age" : {
"type" : "short"
},
"createTime" : {
"type" : "long"
},
"id" : {
"type" : "integer"
},
"updateTime" : {
"type" : "long"
},
"userName" : {
"type" : "keyword"
}
}
}
}
同步數(shù)據(jù)到新索引
POST _reindex
{
"source": {
"index": "user_index"
},
"dest": {
"index": "user_index1"
}
}
刪除舊索引
DELETE user_index
創(chuàng)建舊索引
PUT user_index
{
"mappings" : {
"properties" : {
"age" : {
"type" : "short"
},
"createTime" : {
"type" : "long"
},
"id" : {
"type" : "integer"
},
"updateTime" : {
"type" : "long"
},
"userName" : {
"type" : "keyword"
}
}
}
}
同步數(shù)據(jù)到舊索引
POST _reindex
{
"source": {
"index": "user_index1"
},
"dest": {
"index": "user_index"
}
}
刪除新索引
DELETE user_index1
到了這里,關(guān)于Spring Boot集成ES7.10的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!