文章目錄
- Elaticsearch 學習筆記
- 一、什么是 Elaticsearch ?
- 二、Elaticsearch 安裝
- 1 es 安裝
- 2 問題解決
- 3 數據格式
- 三、索引操作
- 1 PUT 請求:在postman中,向 ES 服務器發 PUT 請求(PUT請求相當于創建的意思)
- 2 GET 請求:GET 請求是獲取的意思,獲取指定的索引
- 3 GET 請求獲取全部索引
- 4 DELETE:刪除索引
- 四、文檔操作
- 1 POST請求創建文檔
- 2 GET請求查詢文檔
- 3 GET請求條件查詢
- 4 GET請求分頁查詢
- 5 GET請求查詢后排序
- 6 GET多條件查詢
- 7 GET范圍查詢
- 8 PUT請求修改文檔-全部覆蓋:在請求體內貼入需修改的數據
- 9 DELETE請求刪除文檔
- 10 全文檢索與部分檢索:match_phrase & match
- 11 檢索結果高亮顯示
- 12 聚合查詢-平均值
- 五、Java API 操作
- 1 創建maven項目,添加依賴
- 2 索引創建
- 3 索引查看
- 4 索引刪除
- 5 向索引新增元素
- 6 在索引中修改元素
- 7 在索引中查看元素
- 8 在索引中刪除元素
- 9 在索引中批量新增元素
- 10 在索引中批量刪除元素
- 11 高級查詢-全量查詢:QueryBuilders.matchAllQuery()
- 12 高級查詢-條件查詢:QueryBuilders.termQuery()
- 13 高級查詢-分頁查詢:builder.from(x);builder.size(y)
- 14 高級查詢-查詢排序:builder.sort()
- 15 高級查詢-排除/包含字段:builder.sort()
- 16 高級查詢-組合查詢
Elaticsearch 學習筆記
一、什么是 Elaticsearch ?
Elasticsearch 是一個分布式、RESTful 風格的搜索和數據分析引擎,能夠解決不斷涌現出的各種用例。作為 ElasticStack 的核心,它集中存儲您的數據,幫助您發現意料之中以及意料之外的情況。
The Elastic Stack,包括 Elasticsearch、Kibana、Beats 和 Logstash (也稱為 ELK Stack)能夠安全可靠地獲取任何來源、任何格式的數據,然后實時地對數據進行搜索、分析和可視化。Elaticsearch,簡稱為ES,ES 是一個開源的高擴展的分布式全文搜索引擎,是整個 ElasticStack 技術棧的核心。它可以近乎實時的存儲、檢索數據:本身擴展性很好,可以擴展到上百臺服務器,處理 PB 級別的數據。
二、Elaticsearch 安裝
1 es 安裝
Elaticsearch 官網地址:https://www.elastic.co/cn/
由于我的環境是 windows 環境,因此下載 windows 安裝包即可。
下載完windows 安裝包后,直接解壓即可:
注意:9300端口為 es 集群間通信的端口,9200為瀏覽器訪問的 http 協議 的restful 端口。
啟動后瀏覽器訪問:
http://localhost:9200/
出現以下頁面則成功啟動:
2 問題解決
-
es 是使用 java 開發的,且 7.8 版本的 es 需要jdk 1.8以上,默認安裝包帶有 jdk 環境,如果系統配置 JAVA HOME,那么使用系統默認的 jdk,如果沒有配置使用自帶的 jdk,一般建議使用系統配置的 jdk。
-
雙擊啟動窗口閃退,通過路徑訪問追蹤錯誤,如果是“空間不足”,請修改 config/jvm.options 配置文件:
# 設置 JVM 初始內存為1G。此值可以設置與-Xmx 相同,以避免每次垃圾回收完成后 JVM 重新分配內存 # Xms represents the initial size of total heap space # 設置 JVM 最大可用內存為 1G # Xmx represents the maximum size of total heap space -Xms1g -Xmx1g
3 數據格式
Elasticsearch 是面向文檔型數據庫,一條數據在這里就是一個文檔。為了方便理解,我們將 Elasticsearch 里存儲文檔數據和關系型數據庫 MySQL 存儲數據的概念進行一個類比
ES 里的 Index 可以看作一個庫,而 Types 相當于表,Documents 則相當于表的行。
三、索引操作
對比關系型數據庫,創建索引就等同于創建數據庫。
1 PUT 請求:在postman中,向 ES 服務器發 PUT 請求(PUT請求相當于創建的意思)
http://127.0.0.1:9200/shopping
2 GET 請求:GET 請求是獲取的意思,獲取指定的索引
http://127.0.0.1:9200/shopping
3 GET 請求獲取全部索引
http://127.0.0.1:9200/_cat/indices?v
4 DELETE:刪除索引
http://127.0.0.1:9200/shopping
四、文檔操作
1 POST請求創建文檔
http://127.0.0.1:9200/shopping/_doc
{"title": "小米手機","category": "小米","images": "https://ts1.cn.mm.bing.net/th?id=OIP-C.NelZaFZYimRWyjjIrjd-QQHaGM&w=273&h=228&c=8&rs=1&qlt=90&o=6&pid=3.1&rm=2","price": 3999.00
}
這里的id是隨機生成的,也可以采用put請求直接傳入id:
http://127.0.0.1:9200/shopping/_doc/1001
2 GET請求查詢文檔
如果只查詢某個指定的id,則在路徑中直接指定即可:
// 在路徑中指定id
http://127.0.0.1:9200/shopping/_doc/1001
如果要查詢全部:
// 指定index并且使用_search
http://127.0.0.1:9200/shopping/_search
3 GET請求條件查詢
http://127.0.0.1:9200/shopping/_search?q=category:小米
上述條件會查詢出所有 category 字段為小米的元素。
直接在請求路徑中拼接中文,很有可能會亂碼,因此我們采用請求體查詢:
http://127.0.0.1:9200/shopping/_search
{"query" : {"match": {"category" : "小米"}}
}
4 GET請求分頁查詢
在請求體中加入from和size即可。
http://127.0.0.1:9200/shopping/_search
{"query" : {"match": {"category" : "小米"}},"from": 0,"size": 2
}
5 GET請求查詢后排序
http://127.0.0.1:9200/shopping/_search
{"query" : {"match": {"category" : "小米"}},"from": 0,"size": 2,"sort": {"price": {"order": "desc" // asc}}
}
6 GET多條件查詢
http://127.0.0.1:9200/shopping/_search
{"query" : {"bool": {"must": [{"match": {"category": "小米"}}, // 多條件{"match": {"price": "4999.00"}} // 多條件]}},"from": 0,"size": 2,"sort": {"price": {"order": "desc" // asc}}
}
一個條件符合多值:
{"query" : {"bool": {"should": [ // 一個條件符合多值{"match": {"category": "小米"}}, // 多值{"match": {"category": "華為"}} // 多值]}},"from": 0,"size": 2,"sort": {"price": {"order": "desc" // asc}}
}
7 GET范圍查詢
http://127.0.0.1:9200/shopping/_search
{"query" : {"bool": {"must": [{"match": {"category": "小米"}}],"filter" :{"range": {"price": {"gt": 3000, // 大于3000 && 小于8000"lt": 8000}}}}},"from": 0,"size": 2,"sort": {"price": {"order": "desc" // asc}}
}
8 PUT請求修改文檔-全部覆蓋:在請求體內貼入需修改的數據
http://127.0.0.1:9200/shopping/_doc/1001
{"title": "小米手機","category": "小米","images": "https://ts1.cn.mm.bing.net/th?id=OIP-C.NelZaFZYimRWyjjIrjd-QQHaGM&w=273&h=228&c=8&rs=1&qlt=90&o=6&pid=3.1&rm=2","price": 4999.00
}
如果只修改指定的屬性,則使用post請求:
http://127.0.0.1:9200/shopping/_update/1001
9 DELETE請求刪除文檔
http://127.0.0.1:9200/shopping/_doc/1001
10 全文檢索與部分檢索:match_phrase & match
http://127.0.0.1:9200/shopping/_search
此處使用match是全文檢索,es會把小華拆分成"小"、"華"兩個字符單獨匹配,因此查詢結果會把字段category 包含"小"字、"華"字的元素都查詢出來。
如果要實現完全匹配,則使用:match_phrase 。
{"query" : {"bool": {"must": [{"match_phrase": {"category": "小華"}}]}}
}
這時查詢出來的結果集就是category 為小華的元素,如果沒有,則是null。
11 檢索結果高亮顯示
http://127.0.0.1:9200/shopping/_search
{"query" : {"bool": {"must": [{"match_phrase": {"category": "小米"}}]}},"highlight": {"fields" : {"category": {} // 對category這個字段進行高亮顯示}}
}
12 聚合查詢-平均值
http://127.0.0.1:9200/shopping/_search
聚合查詢:
{ "aggs" : {"price_group【價格分組】": {"terms": {"field": "price"}}}
}
求平均值:
{ "aggs" : {"price_avg【價格平均值】": {"avg": {"field": "price"}}}
}
五、Java API 操作
Elasticsearch 軟件是由Java 語言開發的,所以也可以通過 Java API 的方式對 Elasticsearch 服務進行訪問。
1 創建maven項目,添加依賴
<!-- es 依賴 -->
<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version>
</dependency><!-- es的客戶端 -->
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.8.0</version>
</dependency>
創建客戶端連接:
public class ESTestClient {public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
}
2 索引創建
public class ESTestCreatIndex {public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 創建索引CreateIndexRequest user = new CreateIndexRequest("user"); // user: 索引名try {CreateIndexResponse createIndexResponse = esClient.indices().create(user, RequestOptions.DEFAULT);// 響應狀態boolean acknowledged = createIndexResponse.isAcknowledged();System.out.println("索引操作:" + acknowledged);} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}}
3 索引查看
public class ESTestCreatIndex {public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 查詢索引GetIndexRequest request = new GetIndexRequest("user"); // 獲取user索引try {GetIndexResponse getIndexResponse = esClient.indices().get(request, RequestOptions.DEFAULT);System.out.println(getIndexResponse.getAliases());System.out.println(getIndexResponse.getMappings());System.out.println(getIndexResponse.getSettings());} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}}
4 索引刪除
public class ESTestDeleteIndex {public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 刪除索引DeleteIndexRequest request = new DeleteIndexRequest("user"); // 刪除user索引try {AcknowledgedResponse deleteResponse = esClient.indices().delete(request, RequestOptions.DEFAULT);System.out.println(deleteResponse.isAcknowledged());} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}}
5 向索引新增元素
public class ESTestDocInsert {public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 插入數據IndexRequest request = new IndexRequest();request.index("user").id("1004");User user = new User();user.setName("張三");user.setAge(20);user.setSex("男");try {// 向es插入數據,必須將數據轉換為json格式ObjectMapper objectMapper = new ObjectMapper();String userJson = objectMapper.writeValueAsString(user);request.source(userJson, XContentType.JSON);IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);System.out.println(response.getResult());} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
}
6 在索引中修改元素
public class ESTestDocUpdate {public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 更新數據UpdateRequest request = new UpdateRequest();request.index("user").id("1004"); // 傳入索引和idrequest.doc(XContentType.JSON, "sex", "女"); // 把性別改為女try {UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT);System.out.println(response.getResult());} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
}
7 在索引中查看元素
public class ESTestDocGet {public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 查詢數據GetRequest request = new GetRequest();request.index("user").id("1004"); // 傳入索引和idtry {GetResponse response = esClient.get(request, RequestOptions.DEFAULT);System.out.println(response.getSourceAsString());} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
}
8 在索引中刪除元素
public class ESTestDocDelete {public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 刪除數據DeleteRequest request = new DeleteRequest();request.index("user").id("1004"); // 傳入索引和idtry {DeleteResponse response = esClient.delete(request, RequestOptions.DEFAULT);System.out.println(response.getResult());} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
}
9 在索引中批量新增元素
public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 批量插入數據BulkRequest request = new BulkRequest();for (int i = 0; i < 3; i++) {IndexRequest indexRequest = new IndexRequest("user").id("1001" + i).source(XContentType.JSON, "name", "張三" + i);request.add(indexRequest);}try {BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);System.out.println(response.getTook()); // 花費的時間System.out.println(response.getItems()); // 多個響應} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
10 在索引中批量刪除元素
public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 批量刪除數據BulkRequest request = new BulkRequest();for (int i = 0; i < 3; i++) {DeleteRequest indexRequest = new DeleteRequest("user").id("1001" + i);request.add(indexRequest);}try {BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);System.out.println(response.getTook()); // 花費的時間System.out.println(response.getItems()); // 多個響應} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
11 高級查詢-全量查詢:QueryBuilders.matchAllQuery()
public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 高級查詢-全量查詢SearchRequest request = new SearchRequest();request.indices("user");request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));try {SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);System.out.println(response.getHits().getTotalHits()); // 獲取user索引中元素的個數System.out.println(response.getTook()); // 獲取時間for (SearchHit hit : response.getHits()) {System.out.println(hit.getSourceAsString()); // 按字符串打印元素的全部屬性System.out.println(hit); // 一個元素的全部數據 json 格式System.out.println(hit.getId()); // 打印id}} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
12 高級查詢-條件查詢:QueryBuilders.termQuery()
public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 高級查詢-全量查詢SearchRequest request = new SearchRequest();request.indices("user");request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age", 22))); // 把年齡為22歲的查詢出來try {SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);System.out.println(response.getHits().getTotalHits()); // 獲取user索引中元素的個數System.out.println(response.getTook()); // 獲取時間for (SearchHit hit : response.getHits()) {System.out.println(hit.getSourceAsString()); // 按字符串打印元素的全部屬性System.out.println(hit); // 一個元素的全部數據 json 格式System.out.println(hit.getId()); // 打印id}} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
13 高級查詢-分頁查詢:builder.from(x);builder.size(y)
public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 查詢數據SearchRequest request = new SearchRequest();request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());builder.from(0); // 從第幾條數據開始builder.size(3); // 每頁查詢3條數據request.source(builder);try {SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);System.out.println(response.getHits().getTotalHits()); // 獲取user索引中元素的個數System.out.println(response.getTook()); // 獲取時間for (SearchHit hit : response.getHits()) {System.out.println(hit.getSourceAsString()); // 只打印name}} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
14 高級查詢-查詢排序:builder.sort()
public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 查詢數據SearchRequest request = new SearchRequest();request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());builder.sort("age", SortOrder.DESC); // SortOrder.ASCrequest.source(builder);try {SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);System.out.println(response.getHits().getTotalHits()); // 獲取user索引中元素的個數System.out.println(response.getTook()); // 獲取時間for (SearchHit hit : response.getHits()) {System.out.println(hit.getSourceAsString()); // 只打印name}} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
15 高級查詢-排除/包含字段:builder.sort()
public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 查詢數據SearchRequest request = new SearchRequest();request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());String[] excludes = {"name"}; // 排除某個字段String[] includes = {}; // 包含某個字段builder.fetchSource(includes, excludes); // SortOrder.ASCrequest.source(builder);try {SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);System.out.println(response.getHits().getTotalHits()); // 獲取user索引中元素的個數System.out.println(response.getTook()); // 獲取時間for (SearchHit hit : response.getHits()) {System.out.println(hit.getSourceAsString()); // 只打印name}} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}
16 高級查詢-組合查詢
public static void main(String[] args) {// 創建es客戶端RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));// 查詢數據SearchRequest request = new SearchRequest();request.indices("user");SearchSourceBuilder builder = new SearchSourceBuilder();BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();boolQueryBuilder.must(QueryBuilders.matchQuery("age", 24)); // age必須是25boolQueryBuilder.mustNot(QueryBuilders.matchQuery("sex", "男")); // sex必須不能是男builder.query(boolQueryBuilder);request.source();try {SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);System.out.println(response.getHits().getTotalHits()); // 獲取user索引中元素的個數System.out.println(response.getTook()); // 獲取時間for (SearchHit hit : response.getHits()) {System.out.println(hit.getSourceAsString()); // 只打印name}} catch (IOException e) {e.printStackTrace();}// 關閉es客戶端try {esClient.close();} catch (IOException e) {e.printStackTrace();}}