# ik_smart最少切分
GET _analyze
{
"analyzer": "ik_smart",
"text": "河南科技大學"
}
# ik_max_word 最細粒度劃分!窮盡詞庫所有可能
GET _analyze
{
"analyzer": "ik_max_word",
"text": "河南科技大學"
}
# ===================ES索引相關的基本操作=======================
# 建立索引(資料庫)
# 索引庫名稱:csp ,文檔類型名稱:mytype ,文檔id:1
PUT /csp/mytype/1
{
"name":"興趣使然的草帽路飛",
"age":"22"
}
# 建立一個csp2索引庫:
# 索引庫名稱:csp2
# 索引庫中3個字段:name,age,birthday
# 3個字段的類型為:text,integer,date
PUT /csp2
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"age":{
"type": "integer"
},
"birthday":{
"type": "date"
}
}
}
}
# 獲得索引csp2的相關資訊
GET csp2
# 建立索引csp3,文檔類型使用預設的_doc,文檔id:1
# 資料為:nage,age,birthday
PUT /csp3/_doc/1
{
"name":"興趣使然的草帽路飛",
"age":22,
"birthday":"1999-01-29"
}
# 檢視索引csp3預設的資訊
GET csp3
# 檢視es健康狀态
GET _cat/health
# 檢視所有索引庫簡要資訊
GET _cat/indices?v
# 修改索引csp3資料
# 修改的字段name
POST /csp3/_doc/1/_update
{
"doc":{
"name":"海賊王路飛"
}
}
# 删除csp索引庫
DELETE csp
# ===================ES文檔相關的基本操作=======================
# 建立索引my_index,文檔類型user,文檔id:1
# user:1
PUT /my_index/user/1
{
"name":"草帽路飛",
"age":22,
"description":"海賊王,我當定了!",
"tags":["吃貨","船長","未來的海賊王","橡膠果實能力者"]
}
# user:2
PUT /my_index/user/4
{
"name":"海賊獵人索隆1",
"age":22,
"description":"背後的傷疤,是劍士的恥辱!",
"tags":["路癡","副船長","未來的世界第一大劍豪","三刀流劍客"]
}
PUT /my_index/user/5
{
"name":"海賊獵人索隆2",
"age":25,
"description":"背後的傷疤,是劍士的恥辱!",
"tags":["路癡","副船長","未來的世界第一大劍豪","三刀流劍客"]
}
PUT /my_index/user/2
{
"name":"海賊獵人索隆3",
"age":24,
"description":"背後的傷疤,是劍士的恥辱!",
"tags":["路癡","副船長","未來的世界第一大劍豪","三刀流劍客"]
}
# user:3
PUT /my_index/user/3
{
"name":"黑足山治",
"age":22,
"description":"為了天下女性而活!",
"tags":["色胚","廚師","未來海賊王船上的初始","踢技炫酷"]
}
# 擷取資料
# 擷取user:1
GET /my_index/user/1
# 搜尋資料
GET /my_index/user/_search?q=name:路飛
# 搜尋資料,通過json建構查詢參數
# 搜尋得到的結果中:
# hits: 表示索引和文檔相關資訊
# "total":
# "value": 查詢到的結果的總記錄數
# "relation": 搜尋結果和搜尋參數的關系:eq表示相等 lt小于 gt大于
# "_index": 表示索引名稱
# "_tyoe": 表示文檔類型
# "_id": 表示文檔id
# "_score": 表示搜尋結果的權重
# "_source": 表示文檔中的資料
# 文檔中資料的字段名稱以及值
GET /my_index/user/_search
{
"query": {
"match": {
"name": "索隆"
}
}
}
# 搜尋資料,通過json建構查詢參數,加上結果過濾
# query:建構要搜尋的條件,match:建構要比對的内容
# _source: 結果過濾,隻擷取name和age字段資料
# sort: 排序條件 age:要排序的字段 order:desc 降序
# from:從第幾條資料開始0表示第一條,size:每頁顯示幾條資料
GET /my_index/user/_search
{
"query": {
"match": {
"name": "索隆"
}
},
"_source": ["name","age"],
"sort": [
{
"age": {
"order": "desc"
}
}
],
"from": 0,
"size": 1
}
# 搜尋資料:使用bool多條件精确查詢
# 查詢22歲的所有使用者,且名字中帶有索隆的
# bool: 多條件精确查詢
# must: [] 數組中的所有條件都需要符合 === 且and的關系
GET /my_index/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"age": "22"
}
},
{
"match": {
"name": "索隆"
}
}
]
}
}
}
# 搜尋資料:使用bool多條件精确查詢
# 查詢22歲的所有使用者,或者名字中帶有索隆的所有使用者
# bool: 多條件精确查詢
# shoud: [] 數組中的所有條件隻要有一個符合就行 === 或or的關系
GET /my_index/user/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"age": "22"
}
},
{
"match": {
"name": "索隆"
}
}
]
}
}
}
# 搜尋資料:使用bool多條件精确查詢,filter過濾
# 查詢所有使用者,名字中有索隆的,且年齡在22-25之間
# bool: 多條件精确查詢,filter:按照字段過濾 === gt lt eq gte大于等于 lte 小于等于
GET /my_index/user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "索隆"
}
}
],
"filter": {
"range": {
"age": {
"lt": 22,
"gt": 25
}
}
}
}
}
}
# 根據tags數組中的内容搜尋,以空格分割查詢條件
# 結果:可以得到路飛和山治的資訊
GET /my_index/user/_search
{
"query": {
"match": {
"tags": "廚師 船長"
}
}
}
# 精确查詢:
# term: 精确查詢,直接通過反向索引指定的詞條進行精确查找
# match: 會使用分詞器解析(先分析文檔,然後再通過分析的文檔進行查詢)
# 兩個類型: text 和 keyword
# 建立一個索引
PUT my_index2
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"description":{
"type": "keyword"
}
}
}
}
# 向my_index2插入資料
PUT /my_index2/_doc/1
{
"name":"蒙奇D路飛",
"description":"海賊王我當定了!"
}
# 使用分詞器查詢
# "analyzer": "keyword" 使用ik分詞器查詢
GET _analyze
{
"analyzer": "keyword",
"text": "海賊王我當定了!"
}
# 使用分詞器查詢
# "analyzer": "standard" 使用預設分詞器查詢
# 該分詞器會逐個拆分每個詞(字)
GET _analyze
{
"analyzer": "standard",
"text": "海賊王我當定了!"
}
# term 精确查詢
# 由結果得出:
# keyword類型(description)的字段不會被分詞器解析
# text類型(name)的字段會被分詞器解析
GET /my_index2/_search
{
"query": {
"term": {
"name": {
"value": "路"
}
}
}
}
# 插入模拟資料
PUT /my_index2/_doc/3
{
"t1":"33",
"t2":"2020-1-17"
}
PUT /my_index2/_doc/4
{
"t1":"44",
"t2":"2020-1-18"
}
PUT /my_index2/_doc/5
{
"t1":"55",
"t2":"2020-1-19"
}
PUT /my_index2/_doc/6
{
"t1":"66",
"t2":"2020-1-20"
}
# 精确查詢多個值
GET /my_index2/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"t1": {
"value": "44"
}
}
},
{
"term": {
"t1": {
"value": "55"
}
}
}
]
}
}
}
# (重點)高亮查詢:
# highlight:搜尋結果高亮展示
# fields:對應的字段數組
# pre_tags: 高亮展示結果的标簽字首,預設是<em>
# post_tags: 高亮展示結果的标簽字尾,預設是</em>
GET /my_index/user/_search
{
"query": {
"match": {
"name": "索隆"
}
},
"highlight": {
"pre_tags": "<p class='key' style='color:red'>",
"post_tags": "</p>",
"fields": {
"name":{}
}
}
}
SpringBoot整合ES
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
可以在application.yml中配置,也可以使用下面的方法配置:
ElasticSearchConfig.java
/**
* @Auther: csp1999
* @Date: 2020/07/11/15:16
* @Description: ES 用戶端配置
*/
@Configuration // 相當于xml 配置 bean
public class ElasticSearchConfig {
// spring <beans id="restHighLevelClient" class="RestHighLevelClient">
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")));
return client;
}
}
SpringBoot測試類
/**
* @Auther: csp1999
* @Date: 2020/07/11/15:16
* @Description: es7.6.x用戶端測試 API
*/
@SpringBootTest
class HaustEsApiApplicationTests {
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient client;
/**
* 索引的建立 Request: PUT csp_index
*
* @throws IOException
*/
@Test
void testCreateIndex() throws IOException {
// 1.建立索引請求
CreateIndexRequest request = new CreateIndexRequest("csp_index");
// 2.執行建立請求 IndicesClient 請求後獲得響應
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
// 輸出結果
System.out.println(createIndexResponse);// org.elasticsearch.client.indices.CreateIndexResponse@cd831c72
}
/**
* 擷取索引 GET
*
* @throws IOException
*/
@Test
void testExistIndex() throws IOException {
// 1.擷取索引庫的請求
GetIndexRequest request = new GetIndexRequest("csp_index");
// 2.執行擷取索引庫的請求
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
// 輸出結果
System.out.println(exists);// 如果索引庫存在,則輸出:true,否則輸出false
}
/**
* 删除索引 DELETE
*
* @throws IOException
*/
@Test
void testDeleteIndex() throws IOException {
// 1.删除索引庫的請求
DeleteIndexRequest request = new DeleteIndexRequest("csp_index");
// 2.執行删除索引庫的請求
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
// 輸出結果
System.out.println(delete.isAcknowledged());// 删除成功輸出true,否則為false
}
/**
* 添加文檔
*
* @throws IOException
*/
@Test
void testAddDocument() throws IOException {
// 1.建立對象
User user = new User("興趣使然的草帽路飛", 22);
// 2.建立請求
IndexRequest request = new IndexRequest("csp_index");
// 3.建構請求規則:PUT /csp_index/_doc/1
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
//request.timeout("1s");
// 4.将user對象資料放入請求,json 資料: 需要用到fastjson
request.source(JSON.toJSONString(user), XContentType.JSON);
// 5.用戶端發送請求,擷取響應的結果
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
// 輸出結果
// IndexResponse[index=csp_index,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
System.out.println(indexResponse.toString());
System.out.println(indexResponse.status());// CREATED:表示建立成功
}
/**
* 擷取文檔,判斷是否存在
*
* @throws IOException
*/
@Test
void testIsExists() throws IOException {
// 1.判斷文檔是否存在的請求
GetRequest request = new GetRequest("csp_index", "1");
// 2.執行請求:判斷文檔是否存在
boolean exists = client.exists(request, RequestOptions.DEFAULT);
// 輸出結果
System.out.println(exists);// 存在傳回true,否則傳回false
}
/**
* 擷取文檔資訊
*
* @throws IOException
*/
@Test
void testGetDocument() throws IOException {
// 1.擷取文檔資訊的請求
GetRequest getRequest = new GetRequest("csp_index", "1");
// 2.執行擷取文檔資訊的請求
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
// 輸出結果
System.out.println(getResponse.getSourceAsString()); //{"age":22,"name":"興趣使然的草帽路飛"}
System.out.println(getResponse);// 傳回的全部内容和指令 是一樣的:
// {"_index":"csp_index","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"age":22,"name":"興趣使然的草帽路飛"}}
}
/**
* 更新文檔資訊
*
* @throws IOException
*/
@Test
void testUpdateDocument() throws IOException {
// 1.更新文檔請求
UpdateRequest updateRequest = new UpdateRequest("csp_index", "1");
// 設定請求逾時時間
updateRequest.timeout("1s");
// user資料對象封裝到json中
User user = new User("興趣使然的諾諾亞索隆", 23);
updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);
// 2.執行更新文檔請求
UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
// 輸出結果
System.out.println(updateResponse.status());// OK:表示更新成功
}
/**
* 删除文檔記錄
*
* @throws IOException
*/
@Test
void testDeleteDocument() throws IOException {
// 1.删除文檔請求
DeleteRequest deleteRequest = new DeleteRequest("csp_index", "1");
deleteRequest.timeout("1s");
// 2.執行删除文檔請求
DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
// 輸出結果
System.out.println(deleteResponse.status());// OK:表示删除成功
}
/**
* 批量插入資料
*
* @throws IOException
*/
@Test
void testBulkRequest() throws IOException {
// 1.批處理請求
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
// user資料集合
ArrayList<User> list = new ArrayList<>();
list.add(new User("路飛", 1));
list.add(new User("索隆", 2));
list.add(new User("山治", 3));
list.add(new User("娜美", 4));
list.add(new User("羅賓", 5));
list.add(new User("喬巴", 6));
list.add(new User("烏索普", 7));
list.add(new User("弗蘭奇", 8));
list.add(new User("布魯克", 9));
list.add(new User("甚平", 10));
for (int i = 0; i < list.size(); i++) {
// 批量更新,修改,删除 都是在此進行操作
bulkRequest.add(
new IndexRequest("csp_index")
// 批量指派文檔id: 如果不在自己指派文檔id,會預設生成随機的文檔id
.id("" + (i + 1))
// ArrayList轉換成json
.source(JSON.toJSONString(list.get(i)), XContentType.JSON)
);
}
// 2.執行批量插入請求
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
// 輸出結果
System.out.println(bulkResponse.status());// OK: 表示批量插入成功!
}
/**
* ES中資料搜尋:
* SearchRequest 搜尋請求
* SearchRequest 搜尋請求
* SearchSourceBuilder 條件構造
* HighlightBuilder 建構高亮
* TermQueryBuilder 精确查詢
* XXXQueryBuilder 建構我們需要用到的指令
*
* @throws IOException
*/
@Test
void testSearch() throws IOException {
// 1.建立搜尋請求
SearchRequest searchRequest = new SearchRequest("csp_index");
// 2.建構搜尋條件:條件構造器SearchSourceBuilder
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 高亮結果的條件構造器
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("name");// 要高亮的字段
highlightBuilder.requireFieldMatch(false);// 不需要多個字段高亮,如果需要設定為true
highlightBuilder.preTags("<span style='color:red'>");
highlightBuilder.postTags("</span>");
// 條件構造器,開啟搜尋結果高亮,并加入高亮結果的條件構造器
sourceBuilder.highlighter(highlightBuilder);
/**
* 查詢條件,使用QueryBuilders工具類來實作:
* QueryBuilders.termQuery() 精确查詢
* QueryBuilders.matchAllQuery() 比對所有
*/
//TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "csp");// 精确查詢
//MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();// 搜尋所有資料
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "路飛");// 搜尋字段name為路飛的資料
// 查詢條件(matchQueryBuilder)放入條件構造器
sourceBuilder.query(matchQueryBuilder);
// 條件構造器,開啟分頁條件: 從第1個資料開始,每頁展示5條結果資料
sourceBuilder.from(0);
sourceBuilder.size(5);
// 條件構造器,搜尋請求逾時時間60s
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
// 将條件構造器放入搜尋請求
searchRequest.source(sourceBuilder);
// 執行搜尋請求,并獲得searchResponse響應
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 搜尋得到的所有結果都封裝在hits裡面,拿資料從hits裡面擷取
SearchHits hits = searchResponse.getHits();
//System.out.println(JSON.toJSONString(hits));
// 周遊hits:解析結果,并将結果放入resultList集合
ArrayList<Map<String, Object>> resultList = new ArrayList<>();
for (SearchHit documentFields : searchResponse.getHits().getHits()) {
// 擷取高亮的字段
Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
HighlightField name = highlightFields.get("name");// 擷取高亮的字段
Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();// 先擷取原來未高亮的結果
// 解析高亮的字段, 将原來未高亮的title字段換成高亮的字段
if (name != null) {
Text[] fragments = name.fragments();
String newName = "";
for (Text text : fragments) {
newName += text;
}
// 高亮字段替換原來内容
sourceAsMap.put("name", newName);
}
resultList.add(documentFields.getSourceAsMap());
}
// 周遊resultList
resultList.forEach(item -> {
System.out.println(item);// {name=<span style='color:red'>路</span><span style='color:red'>飛</span>, age=1}
});
}
}