elasticsearch 6.x 與elasticsearch 7.x 配置與使用(Java)
前些天看完了一本關於elasticsearch的書籍,並且做了一個elasticsearch相關專案,對與es也算是有了一定程度的瞭解,不過看書向來都是一邊看一邊忘的,以此文章記錄一些es的簡單用法。
依賴
由於本人用的es版本為es 7.2的映象,故所有依賴都是es 7.2 版本。以下為依賴程式碼。
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.2.0</version>
</dependency>
<!--這個依賴 7.x 版本可以不新增,但是由於本人程式碼用到,所以不去除-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>7.2.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.2.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.2.0</version>
</dependency>
配置
下面為ElasticsearchConfig的配置程式碼
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetAddress;
/**
* @Author lidai
* @Date 2020/1/7 16:20
*/
@Configuration
public class ElasticsearchConfig {
@Value("${elasticsearch.host}")
private String host;
@Value("${elasticsearch.port}")
private int port;
@Value("${elasticsearch.scheme}")
private String scheme;
@Value("${elasticsearch.timeout}")
private int timeout;
@Bean(name = "highLevelClient")
public RestHighLevelClient restHighLevelClient() {
//可以傳httpHost陣列
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port, scheme));
builder.setRequestConfigCallback(requestConfigBuilder -> {
//設定超時
return requestConfigBuilder.setSocketTimeout(timeout);
});
return new RestHighLevelClient(builder);
}
/**
* es7 已廢棄 TransportClient,但是程式碼記錄中用到,故留存。7.x版本可以直接捨棄
*
* @return
*/
@Bean
public TransportClient transportClient() {
try {
Settings settings = Settings.builder().put("cluster.name", "elasticsearch")
.put("client.transport.sniff", true)
.build();
TransportClient transportClient = new PreBuiltTransportClient(settings);
TransportAddress address = new TransportAddress(InetAddress.getByName(host), port);
transportClient.addTransportAddress(address);
return transportClient;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
工具類
es 6.x中好像在儲存或修改時不能直接使用json字串了(我記得是這樣,如果能用就更好了),所以需要使用XContentBuilder來對欄位進行處理,以下是一個處理的工具類
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.Map;
/**
* @Author lidai
* @Date 2020/1/7 18:14
*/
public class ElasticsearchUtils {
/**
* 將實體轉化為 XContentBuilder 以便儲存es
*
* @param xContentBuilder
* @param object
* @return
*/
public static XContentBuilder objectToXContentBuilder(XContentBuilder xContentBuilder, Object object) {
try {
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(object));
xContentBuilder.startObject();
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
xContentBuilder.field(entry.getKey(), entry.getValue());
}
xContentBuilder.endObject();
} catch (IOException e) {
e.printStackTrace();
}
return xContentBuilder;
}
}
示例程式碼
以下為增刪改查的Java示例程式碼 ,目前程式碼都是es6.x版本,7.x版本有時間在加上去。值得注意的是es7.x中 TransportClient類已經過期。所以以下示例程式碼中凡是使用TransportClient的示例程式碼均為 elasticsearch 6.x 版本。
import com.alibaba.fastjson.JSONObject;
import com.demo.interview.es.domain.ElasticsearchPage;
import com.demo.interview.es.domain.Person;
import com.demo.interview.es.utils.ElasticsearchUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeRequest;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
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.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @Author lidai
* @Date 2020/1/7 18:12
*/
@Slf4j
@RestController
@RequestMapping("/elasticsearch")
public class ElasticsearchController {
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
static DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
static Person person = new Person(1L, "test", 20, 0, LocalDate.parse("2020-01-01").format(formatter), "備註", LocalDateTime.now().format(formatter2));
final String DEMO_INDEX = "demo_index";
final String DEMO_TYPE = "demo_type";
@Autowired
@Qualifier(value = "highLevelClient")
private RestHighLevelClient highLevelClient;
@Autowired
private TransportClient transportClient;
/**
* 新增
*
* @param person
* @throws Exception
*/
public void createIndex(Person person) throws Exception {
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder();
xContentBuilder = ElasticsearchUtils.objectToXContentBuilder(xContentBuilder, person);
//建立索引
IndexResponse indexResponse = transportClient.prepareIndex(DEMO_INDEX, DEMO_TYPE, person.getId().toString())
.setSource(xContentBuilder)
//立即生效,無此需求可以不設定
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.execute().actionGet();
}
/**
* 修改
*
* @param object
* @throws IOException
*/
public void updateIndex(Person person) throws IOException {
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder();
xContentBuilder = ElasticsearchUtils.objectToXContentBuilder(xContentBuilder, person);
UpdateResponse updateResponse = transportClient.prepareUpdate(DEMO_INDEX, DEMO_TYPE, person.getId().toString())
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.setDoc(xContentBuilder).get();
}
/**
* 批量修改
*
* @param ids
* @throws IOException
*/
public void batchUpdate(String[] ids) throws IOException {
BulkRequestBuilder bulkRequestBuilder = transportClient.prepareBulk();
for (String id : ids) {
bulkRequestBuilder.add(transportClient.prepareUpdate(DEMO_INDEX, DEMO_TYPE, id)
.setDoc(XContentFactory.jsonBuilder().startObject().field("deleted", 1).endObject()));
}
BulkResponse response = bulkRequestBuilder.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).get();
if (response.hasFailures()) {
throw new ElasticsearchException(response.buildFailureMessage());
}
}
/**
* 批量新增
*
* @param persons
* @throws IOException
*/
public void batchInsert(List<Person> persons) throws IOException {
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder();
BulkRequestBuilder bulkRequestBuilder = transportClient.prepareBulk();
//新增es
for (Person person : persons) {
//注意批量操作時資料為null會報異常
bulkRequestBuilder.add(transportClient.prepareIndex(DEMO_INDEX, DEMO_TYPE, person.getId().toString())
.setSource(ElasticsearchUtils.objectToXContentBuilder(xContentBuilder, person)));
}
BulkResponse responses = bulkRequestBuilder.get();
if (responses.hasFailures()) {
throw new ElasticsearchException(responses.buildFailureMessage());
}
}
/**
* 搜尋示例
*
* @param params
* @return
*/
public ElasticsearchPage<Person> searchDemo(Map<String, Object> params) {
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.termQuery("deleted", 0));
String keyword = (String) params.get("keyword");
Integer news = (Integer) params.get("news");
Integer status = (Integer) params.get("status");
Integer columnCategory = (Integer) params.get("columnCategory");
String year = (String) params.get("year");
Integer pageSize = (Integer) params.get("pageSize");
Integer pageNum = (Integer) params.get("pageNum");
String[] messageColumn = {"messageTitle", "messageSource", "content", "tags", "issuer"};
//keyword欄位類別搜尋
if (news != null && StringUtils.hasText(keyword)) {
switch (news) {
case 1:
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(keyword, messageColumn));
break;
case 2:
boolQueryBuilder.must(QueryBuilders.matchQuery("messageTitle", keyword));
break;
case 3:
boolQueryBuilder.must(QueryBuilders.matchQuery("content", keyword));
break;
case 4:
boolQueryBuilder.must(QueryBuilders.matchQuery("messageSource", keyword));
break;
case 5:
boolQueryBuilder.must(QueryBuilders.matchQuery("tags", keyword));
break;
case 6:
boolQueryBuilder.must(QueryBuilders.matchQuery("issuer", keyword));
break;
default:
break;
}
}
//釋出狀態搜尋
if (status != null) {
switch (status) {
case 1:
boolQueryBuilder.must(QueryBuilders.matchAllQuery());
break;
case 2:
boolQueryBuilder.must(QueryBuilders.termQuery("status", 2));
break;
case 3:
boolQueryBuilder.must(QueryBuilders.termQuery("status", 3));
break;
default:
break;
}
}
//欄目類別搜尋
if (columnCategory != null) {
switch (columnCategory) {
case 1:
boolQueryBuilder.must(QueryBuilders.matchAllQuery());
break;
case 2:
boolQueryBuilder.must(QueryBuilders.termQuery("columnCategory", 2));
break;
case 3:
boolQueryBuilder.must(QueryBuilders.termQuery("columnCategory", 3));
break;
default:
break;
}
}
//年份搜尋,多年分傳參形式為{"2016","2017","2018","2019","2020"}
if (StringUtils.hasText(year)) {
try {
Integer y = Integer.valueOf(year);
boolQueryBuilder.must(QueryBuilders.rangeQuery("updateDate").from(year + "-1-1").to(year + "-12-31"));
} catch (NumberFormatException e) {
String[] yearList = year.split(",");
int max = Arrays.stream(yearList).mapToInt(Integer::valueOf).max().getAsInt();
int min = Arrays.stream(yearList).mapToInt(Integer::valueOf).min().getAsInt();
boolQueryBuilder.must(QueryBuilders.rangeQuery("updateDate").from(min + "-1-1").to(max + "-12-31"));
}
}
SearchResponse searchResponse = transportClient.prepareSearch(DEMO_INDEX)
.setTypes(DEMO_TYPE)
.setQuery(boolQueryBuilder)
.setFrom((pageNum - 1) * pageSize)
.setSize(pageSize)
.addSort("status", SortOrder.DESC)
.addSort("updateDate", SortOrder.DESC)
.addSort("id", SortOrder.DESC)
.setExplain(true)
.execute()
.actionGet();
SearchHits hits = searchResponse.getHits();
int totalHits = (int) hits.getTotalHits().value;
SearchHit[] searchHits = hits.getHits();
List<Person> persons = new ArrayList<>(10);
for (SearchHit searchHit : searchHits) {
String sourceAsString = searchHit.getSourceAsString();
Person person = JSONObject.parseObject(sourceAsString, Person.class);
persons.add(person);
}
return ElasticsearchPage.<Person>of(pageNum, pageSize, totalHits, persons);
}
/**
* 查詢分詞結果,str為要分析的字串,使用|將分詞結果隔開
*
* @param str
* @return
*/
public String queryAnalyzer(String str) {
if (StringUtils.hasText(str)) {
AnalyzeRequest analyzeRequest = new AnalyzeRequest(DEMO_INDEX).text(str)
.analyzer("ik_max_word");
List<AnalyzeResponse.AnalyzeToken> tokens = this.transportClient.admin().indices().analyze(analyzeRequest)
.actionGet().getTokens();
StringBuilder sb = new StringBuilder();
for (AnalyzeResponse.AnalyzeToken token : tokens) {
sb.append(token.getTerm());
sb.append("|");
}
str = sb.toString().substring(0, sb.toString().length() - 1);
}
return str;
}
}
以上程式碼為求方便並未測試(後續有時間會測試),有問題歡迎指出,謝謝。
另外程式碼中 7.x版本程式碼暫無,有時間再新增。
相關文章
- Elasticsearch 6.x 倒排索引與分詞Elasticsearch索引分詞
- Elasticsearch 7.x 安裝及配置指導Elasticsearch
- Elasticsearch 的配置與使用,為了全文搜尋Elasticsearch
- Elasticsearch 7.x:2、索引管理Elasticsearch索引
- ElasticSearch Java API使用ElasticsearchJavaAPI
- ElasticSearch與SpringBoot的整合與JPA方法的使用ElasticsearchSpring Boot
- ElasticSearch生命週期管理-索引策略配置與操作Elasticsearch索引
- Elasticsearch 第九篇:叢集配置與搭建Elasticsearch
- 使用 Java API 操作 elasticsearchJavaAPIElasticsearch
- ElasticSearch與Spring Boot整合ElasticsearchSpring Boot
- Elasticsearch技術解析與實戰(六)Elasticsearch併發Elasticsearch
- 《Elasticsearch技術解析與實戰》Chapter 1.2 Elasticsearch安裝ElasticsearchAPT
- Elasticsearch 查詢與過濾Elasticsearch
- 《Elasticsearch技術解析與實戰》Chapter 1.4 Spring Boot整合ElasticsearchElasticsearchAPTSpring Boot
- ElasticSearch安裝及java Api使用ElasticsearchJavaAPI
- ElasticSearch—— Java APIElasticsearchJavaAPI
- elasticsearch配置注入索引Elasticsearch索引
- Debezium kafka elasticsearch 配置KafkaElasticsearch
- Elasticsearch 7.x 之節點、叢集、分片及副本Elasticsearch
- 【ElasticSearch】ElasticSearch 7.x 預設不在支援指定索引型別 Failed to parse mapping [_doc]: Root mapping definitioElasticsearch索引型別AIAPP
- elasticsearch(三)----索引建立與刪除Elasticsearch索引
- ClickHouse與Elasticsearch壓測實踐Elasticsearch
- 《Elasticsearch技術解析與實戰》Chapter 1.3 Elasticsearch增刪改查ElasticsearchAPT
- Elasticsearch使用系列-Docker搭建Elasticsearch叢集ElasticsearchDocker
- ElasticSearch 7.X版本19個常用的查詢語句Elasticsearch
- ElasticSearch 學習筆記(一) 基本概念與基本使用Elasticsearch筆記
- ElasticSearch7.6.2在windows上如何配置ik分詞器與用法ElasticsearchWindows分詞
- 《Elasticsearch技術解析與實戰》Chapter 2.1 Elasticsearch索引增刪改查ElasticsearchAPT索引
- 《Elasticsearch技術解析與實戰》Chapter 1.1:Elasticsearch入門和倒排索引ElasticsearchAPT索引
- elasticsearch的使用Elasticsearch
- Elasticsearch 9200自動配置Elasticsearch
- ElasticSearch之網路配置Elasticsearch
- Docker Elasticsearch 叢集配置DockerElasticsearch
- Hive 與 ElasticSearch 的資料互動HiveElasticsearch
- docker安裝elasticsearch與es-headDockerElasticsearch
- elasticsearch Request Body 與 Query DSL詳解Elasticsearch
- Elasticsearch 之 Filter 與 Query 有啥不同?ElasticsearchFilter
- Elasticsearch使用系列-.NET6對接ElasticsearchElasticsearch