Maven學習
Elasticsearch
安裝與使用
下載地址
ElasticSearch: https://mirrors.huaweicloud.com/elasticsearch/?C=N&O=D
logstash: https://mirrors.huaweicloud.com/logstash/?C=N&O=D
kibana: https://mirrors.huaweicloud.com/kibana/?C=N&O=D
ik分詞器: https://github.com/medcl/elasticsearch-analysis-ik/releases
視覺化外掛es head: https://github.com/mobz/elasticsearch-head
ElasticSearch
-
解壓ElasticSearch
-
解壓es head
-
在es head目錄下npm install
-
啟動ElasticSearch
-
訪問http://localhost:9200/檢視是否啟動
-
在es head目錄下npm run start
-
訪問http://localhost:9100/進行連線
-
出現跨域問題,在elasticsearch.yml配置檔案中加入允許跨域
http.cors.enabled: true http.cors.allow-origin: "*"
-
重新啟動並連線
Kibana
-
Kibana版本要與Elasticsearch一致
-
解壓kibana
-
啟動kibana
-
訪問http://localhost:5601/
-
使用中文介面,在kibana.yml中新增
i18n.locale: "zh-CN"
-
重新啟動
ik分詞器
-
ik分詞器版本要與Elasticsearch一致
-
解壓至Elasticsearch的plugins資料夾下
-
啟動Elasticsearch
-
通過命令可以看到一使用的外掛
elasticsearch-plugin list
-
在kibana的控制檯中測試
-
最少切分ik_smart
GET _analyze { "analyzer": "ik_smart" , "text": "大頭兒子" } //分詞結果 { "tokens" : [ { "token" : "大頭", "start_offset" : 0, "end_offset" : 2, "type" : "CN_WORD", "position" : 0 }, { "token" : "兒子", "start_offset" : 2, "end_offset" : 4, "type" : "CN_WORD", "position" : 1 } ] }
-
最細粒度劃分ik_max_word
GET _analyze { "analyzer": "ik_max_word" , "text": "大頭兒子" } //分詞結果 { "tokens" : [ { "token" : "大頭", "start_offset" : 0, "end_offset" : 2, "type" : "CN_WORD", "position" : 0 }, { "token" : "頭兒", "start_offset" : 1, "end_offset" : 3, "type" : "CN_WORD", "position" : 1 }, { "token" : "兒子", "start_offset" : 2, "end_offset" : 4, "type" : "CN_WORD", "position" : 2 } ] }
-
新增自定義詞彙,在config目錄下新建my.dic,加入自定義詞彙"肚肚肚"
-
在IKAnalyzer.cfg.xml中載入自定義詞典
<entry key="ext_dict">my.dic</entry>
-
重啟Elasticsearch
-
測試
GET _analyze { "analyzer": "ik_smart" , "text": "肚肚肚" } //分詞結果 { "tokens" : [ { "token" : "肚肚肚", "start_offset" : 0, "end_offset" : 3, "type" : "CN_WORD", "position" : 0 } ] }
索引操作
新建索引 PUT
PUT /索引名/型別名/文件id
{請求體}
PUT /test1/type1/1
{
#資料請求體
"name": "pinked",
"age": 7
}
PUT test2
{
#規則請求體
"mappings": {
"properties": {
"name": {
"type": "text" #text屬性的欄位會被分詞器解析,keyword屬性的欄位不會
},
"age": {
"type": "integer"
},
"birthday": {
"type": "date"
}
}
}
}
查詢索引 GET
GET 索引名
GET test1
#查詢結果
{
"test1" : {
"aliases" : { },
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"settings" : {
"index" : {
"creation_date" : "1596707098264",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "V4sVrZnuRS-ip_FHbSdupg",
"version" : {
"created" : "7080099"
},
"provided_name" : "test1"
}
}
}
}
更新索引 PUT/POST
#通過PUT覆蓋更新
PUT /test1/type1/1
{
"name": "pinked",
"age": 8
}
#結果
{
"_index" : "test1",
"_type" : "type1",
"_id" : "1",
"_version" : 2, #版本號會增加
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
#通過POST修改更新
POST /test1/_update/1
{
"doc": {
"age": "9"
}
}
#結果
{
"_index" : "test1",
"_type" : "type1",
"_id" : "1",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
刪除索引 DELETE
DELETE test1
文件操作
#新增資料
PUT /pinked/user/1
{
"name": "野原新之助",
"age": 5
}
PUT /pinked/user/2
{
"name": "野比大雄",
"age": 10
}
PUT /pinked/user/3
{
"name": "胖虎",
"age": 10
}
#簡單搜尋
GET /pinked/user/2
#條件搜尋_search?q=k:v
GET /pinked/user/_search?q=age:10
複雜查詢
GET /pinked/user/_search
{
"query": {
"match": {
"name": "野"
}
},
"_source": ["name"], #選擇欄位
"sort": [ #排序
{
"age": {
"order": "desc"
}
}
],
"from": 0, #分頁
"size": 1
}
#多條件查詢
GET /pinked/user/_search
{
"query": {
"bool": {
"must": [ #must同and, should同or
{
"match": {
"name": "野"
}
},
{
"match": {
"age": 5
}
}
]
}
}
}
#
GET /pinked/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "野"
}
}
],
"filter": { #過濾器
"range": { #範圍
"age": {
"gt": 3, #大於3
"lte": 5 #小於等於5
}
}
}
}
}
}
#結果高亮
GET /pinked/user/_search
{
"query": {
"match": {
"name": "野 大"
}
},
"highlight": {
#"pre_tags": "<span style='color:red'>", #自定義標籤字首
#"post_tags": "</span>", #自定義標籤字尾
"fields": {
"name": {} #高亮的欄位,會被<em>標籤包裹
}
}
}
與SpringBoot整合
新建一個springboot專案
相關依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
spring data中匯入的es依賴版本是7.6.2的,可以自定義匯入的版本,儘量與本地的es版本保持一致
<properties>
<java.version>1.8</java.version>
<!--自定義es依賴版本至7.8.0-->
<elasticsearch.version>7.8.0</elasticsearch.version>
</properties>
配置檔案
@Configuration
public class ElasticSearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
return client;
}
}
獲得客戶端
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient client;
索引操作
//建立索引
@Test
void createIndex() throws IOException {
CreateIndexRequest request = new CreateIndexRequest("my_index");
//執行請求
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged());
}
//判斷索引是否存在
@Test
void isIndexExists() throws IOException {
GetIndexRequest request = new GetIndexRequest("my_index");
boolean b = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(b);
}
//刪除索引
@Test
void deleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("my_index");
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged());
}
文件操作
//新增文件
@Test
void insertDoc() throws IOException {
User user = new User("野原新之助", 5);
IndexRequest request = new IndexRequest("my_index");
//設定規則
request.id("1")
.timeout(TimeValue.timeValueSeconds(5))
.source(JSON.toJSONString(user), XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println(response.toString());
System.out.println(response.status());
}
//判斷文件是否存在
@Test
void isDocExists() throws IOException {
GetRequest request = new GetRequest("my_index", "1");
boolean b = client.exists(request, RequestOptions.DEFAULT);
System.out.println(b);
}
//獲取文件
@Test
void getDoc() throws IOException {
GetRequest request = new GetRequest("my_index", "1");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
System.out.println(response);
System.out.println(response.getSourceAsString());
}
//更新文件
@Test
void updateDoc() throws IOException {
User user = new User("野比大雄", 10);
UpdateRequest request = new UpdateRequest("my_index", "1");
request.timeout(TimeValue.timeValueSeconds(5))
.doc(JSON.toJSONString(user), XContentType.JSON);
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
System.out.println(response.status());
}
//刪除文件
@Test
void deleteDoc() throws IOException {
DeleteRequest request = new DeleteRequest("my_index", "1");
request.timeout(TimeValue.timeValueSeconds(5));
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
System.out.println(response.status());
}
//批量操作
@Test
void BulkRequest() throws IOException {
List<User> userList = new ArrayList<>();
userList.add(new User("野原新之助", 5));
userList.add(new User("野比大雄", 10));
userList.add(new User("剛田武", 10));
BulkRequest request = new BulkRequest();
request.timeout(TimeValue.timeValueSeconds(10));
for (int i = 0; i < userList.size(); i++) {
request.add(new IndexRequest("my_index")
.id("" + i + 1)
.source(JSON.toJSONString(userList.get(i)), XContentType.JSON));
}
BulkResponse responses = client.bulk(request, RequestOptions.DEFAULT);
System.out.println(responses.hasFailures());
}
//查詢
@Test
void search() throws IOException {
SearchRequest request = new SearchRequest("my_index");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
TermQueryBuilder query = QueryBuilders.termQuery("username.keyword", "野原新之助");
sourceBuilder.query(query);
sourceBuilder.timeout(TimeValue.timeValueSeconds(10));
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
}