最近博主有一些elasticsearch的工作,所以更新的慢了些,現在就教大家快速入門,并對一些基本的查詢、更新需求做一下示例,廢話不多說開始:
1.?ES快速上手
es下載:[https://elasticsearch.cn/download/]()這里關于es所需要的鏈接基本都有,可以快速下載使用
當你解壓好了歸檔文件之后,Elasticsearch 已經準備好運行了
?1?cd elasticsearch-<version>?2?./bin/elasticsearch?
es默認端口9200;transport端口是9300;transport端口主要用來java客戶端操作,啟動成功后,我們來安裝一下kibana界面操作es的工具,也可以下載header,但是kibana界面比較友好并且最后部署ELK的時候也需要該工具,所以博主就直接安裝kibana了
kibana下載:[https://elasticsearch.cn/download/]()還是跟es一樣的鏈接,下載后解壓并編輯config目錄下編輯kibana.yml文件,主要配置如下:
???1?server.port:?15601?
? ?1?server.host:?"0.0.0.0"?
? ?1?elasticsearch.hosts: ["http://localhost:9200"]?
只需要修改這幾處配置就可以,前提是kibana的版本必須與es的版本是相同的,否則會包很多錯誤,并且啟動失敗,Linux啟動時不能使用root用戶啟動,必須自己添加個人用戶才可以,命令如下:
添加用戶:?1?useradd testuser?
設置密碼:?1?passwd?testuser?
將我們的文件夾用戶權限改變一下要不然啟動時候老是提示沒有權限:?1?chown?-R testuser:testuser kibana?
現在進入我們kibana的文件夾,以testuser啟動kibana:?1?/bin/kibana?
訪問地址:http://localhost:15601
當看到這里的時候就已經OK了,我們終于可以開始使用es了。
我就不介紹es是干啥用的了,es具有分片的概念,分為主分片和副本分片,創建索引的時候一旦設置副本分片,必須有大于等于2臺的機器,每個機器都有es,es之間的交互,需要自己在配置文件中作修改,否則不配置,永遠只是單機,并且主分片在建索引的時候必須考慮清楚減多少個主分片,因為以后如果需要修改主分片,必須重新創建索引,你添加或則減少一個主分片,es往分片中存放數據的時候都會變,但是副本分片不一樣,因為他是數據冗余的,一旦主分片宕機,副本會當選主分片,并且是要主分片存在,副本沒有也可以,副本的作用就是提高數據的吞吐量。好了,開始實戰:
點擊kibana的Dev Tools按鈕,就可以在面板里寫語句操作索引了:
建立索引:shards主分片??replicas副本分片設置的數量,看你有幾臺機器-1
PUT /test {"settings": {"number_of_shards": 5,"number_of_replicas": 1},"mappings": {"_doc": {"properties": {"name": {"type": "text","analyzer": "ik_max_word","search_analyzer": "ik_smart"},"age": {"type":"integer"}}}} }
建立mappings做好字段類型,并且text類型中使用分詞器,不要使用默認的分詞器,默認的分詞器一個漢字分一個,查詢出來基本沒啥價值,中文分詞器是ik,可以上網搜一下下載到es里面。
大家上過語文課,都知道語句有歧義問題,就比如武漢市長江大橋,可以斷成武漢市長、江大橋;武漢市、長江大橋;這就是分詞器如何切分的問題,所以es有關鍵字查詢term,進行完全匹配,不進行分詞器query匹配,除了這些,中文還有同義詞一說,比如蘋果水果與蘋果手機,大家搜索的時候基本都是輸入蘋果,但是出來的卻是蘋果手機,水果很少,這就是因為es也可以做同義詞查詢。但是需要配置同義詞文件,具體操作可以自行上網解決,主要就是創建索引的時候,使用自己在config中編輯的文本文件,該文件中有自己要使用到的同義詞,比如:iPhone,蘋果手機;
我們現在再來進行實戰開發,本人接觸的是使用ElasticsearchRestTemplate進行開發,該類基本含括了大部分需求開發查詢。下面開始舉例:
搜索查詢:
1 String[] includes = new String[] {2 "paperBaseId"3 ,"auditInfoStatus"4 };5 SourceFilter sourceFilter = new FetchSourceFilterBuilder().withIncludes(includes).build();6 SearchQuery searchQuery = new NativeSearchQueryBuilder()7 .withSourceFilter(sourceFilter)8 // 添加查詢條件9 .withQuery(QueryBuilders.termsQuery("paperBaseId",paperBaseId)) 10 .build(); 11 List<EsPaperBase> esPaperBaseList = elasticsearchRestTemplate.queryForList(searchQuery,EsPaperBase.class);
1 //單索引匹配更新 2 Map<String, Object> params = new HashMap<String, Object>();3 params.put("flag", deleteFlag);4 //ctx._source即為該索引本身5 String code = "ctx._source.deleteFlag=params.flag;";6 ScriptType type = ScriptType.INLINE;7 //使用腳本進行更新字段值8 Script script = new Script(type, Script.DEFAULT_SCRIPT_LANG, code, params);9 10 UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(); 11 updateByQueryRequest.indices("exam_information");//設置索引 12 updateByQueryRequest.setDocTypes("doc");//設置文檔,固定doc 13 updateByQueryRequest.setQuery(QueryBuilders.termsQuery("paperBaseId", paperBaseId));//設置查詢 14 updateByQueryRequest.setScript(script);//如果有腳本,則添加 15 updateByQueryRequest.setConflicts("proceed"); // 設置版本沖突時繼續 16 updateByQueryRequest.setRefresh(true);//請求結束后,對我們寫入的索引進行調用刷新 17 this.elasticsearchTemplate.getClient().updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT);//進行更新
1 //多索引匹配批量更新2 Map<String,Object> updateMap = new HashMap<>();3 updateMap.put("deleteFlag",deleteFlag);4 updateMap.put("lastUpdateTime",currDatetime);5 UpdateRequest doc = new UpdateRequest().doc(updateMap);6 List<UpdateQuery> updateQuerys = new ArrayList<>();7 //生成批量更新操作8 paperBaseId.stream().forEach(id ->{9 UpdateQuery build = new UpdateQueryBuilder() 10 .withUpdateRequest(doc) 11 .withDoUpsert(true) 12 .withIndexName("paper_base") 13 .withType("doc") 14 .withId(id).build(); 15 updateQuerys.add(build); 16 }); 17 elasticsearchTemplate.bulkUpdate(updateQuerys,BulkOptions.builder().withRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).build()); 18
1 //查詢操作2 MatchQueryBuilder lastUpdateUser = QueryBuilders.matchQuery("personId", userId);3 MatchQueryBuilder deleteflag = QueryBuilders.matchQuery("deleteFlag", BaseEntity.DEL_FLAG_DELETE);4 //創建bool多條件查詢5 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();6 BoolQueryBuilder mustQuery = boolQueryBuilder.must(lastUpdateUser).must(deleteflag);7 //嵌套索引,需要使用nest查詢8 mustQuery.must(QueryBuilders.nestedQuery("entityNodes", QueryBuilders.termQuery("entityNodes.node_type", recyclePaperDTO.getNodeType()), ScoreMode.None));9 //可以使用should查詢,不是必需條件 10 BoolQueryBuilder nodeQueryBuilder = QueryBuilders.boolQuery(); 11 nodeQueryBuilder.should(QueryBuilders.nestedQuery("entityNodes", QueryBuilders.wildcardQuery("entityNodes.parent_ids", "*," + recyclePaperDTO.getNodeId() + "*"), ScoreMode.None)); 12 nodeQueryBuilder.should(......); 13 mustQuery.must(nodeQueryBuilder); 14 //查詢使用排序 15 SortBuilder order = new FieldSortBuilder("lastUpdateTime").order(SortOrder.DESC); 16 //可以使用高亮顯示,就是html標簽 17 HighlightBuilder highlightBuilder = new HighlightBuilder(); 18 highlightBuilder.preTags("<span class='highlighted'>") 19 .postTags(</span>) 20 .field("paperBaseName");//哪個字段高亮 21 //使用分頁查詢 22 SearchQuery nativeSearchQueryBuilder = new NativeSearchQueryBuilder() 23 .withQuery(mustQuery).withSort(order).withHighlightBuilder(highlightBuilder) 24 .withPageable(PageRequest.of(recyclePaperDTO.getPageNum()-1, recyclePaperDTO.getPageSize())).build(); 25 //進行查詢,entityMapper使用默認的也可,EsPaperBase.class是需要自己映射的查詢類 26 elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder, EsPaperBase.class, new HighlightResultMapper(entityMapper)); 27
1 @Data2 @Builder3 @NoArgsConstructor4 @AllArgsConstructor5 @Document(indexName = "paper_base", type = "doc")6 @Setting(settingPath = "/elasticsearch/settings.json")//可設置主分片、副本分片、設置默認停用詞等7 public class EsPaperBase {8 9 @Id 10 @Field(type = FieldType.Keyword, name = "paperBaseId") 11 private String paperBaseId; 12 13 /** 14 * 試卷名稱 15 */ 16 @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "standard" , name = "paperBaseName"), 17 otherFields = { 18 @InnerField(suffix = "zh", type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart"), 19 @InnerField(suffix = "en", type = FieldType.Text, analyzer = "english"), 20 }) 21 private String paperBaseName; 22 23 /** 24 * 共享級別名,可以使用分詞器查詢,模糊匹配 25 */ 26 @Field(type = FieldType.Text, name = "shareLevelName") 27 private String shareLevelName; 28 29 30 /** 31 * 創建人,不可使用分詞器查詢,精準匹配 32 */ 33 @Field(type = FieldType.Keyword, name = "personId") 34 private String personId; 35 36 37 /** 38 * 創建時間 39 */ 40 @Field(type = FieldType.Date, name = "createtime", format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss") 41 private String createtime; 42 43 /** 44 * 更新時間 45 */ 46 @Field(type = FieldType.Date, name = "lastUpdateTime", format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss") 47 private String lastUpdateTime; 48 49 /** 50 * 刪除標識 0:未刪除,1:已刪除 51 */ 52 @Field(type = FieldType.Keyword, name = "deleteFlag") 53 private String deleteFlag; 54 /** 55 * 試卷推薦,內嵌字段 56 */ 57 @Field(type=FieldType.Nested,name="paperRecommends") 58 private List<EsPaperRecommend> paperRecommends; 59 60 ...... 61 }
1 {//setting.json2 "index": {3 "number_of_shards": "5",4 "number_of_replicas": "2",5 "refresh_interval": "1s",6 "max_rescore_window": 100000007 },8 "analysis": {9 "filter": { 10 "spanish_stop": { 11 "type": "stop", 12 "stopwords": [ "si", "esta", "el", "la" ] 13 }, 14 "light_spanish": { 15 "type": "stemmer", 16 "language": "light_spanish" 17 } 18 }, 19 "analyzer": { 20 "my_spanish": { 21 "tokenizer": "spanish", 22 "filter": [ //順序很重要 23 "lowercase", 24 "asciifolding", 25 "spanish_stop", 26 "light_spanish" 27 ] 28 } 29 } 30 } 31 }
? 現在很多公司基本使用分布式架構應用,公司每個應用模塊都有好幾臺機器,看日志問題也就衍生而來,我們最笨的方法就是每個服務器后臺都打開進行查看,效率低下,此時,我們就可以使用es、kibana、logstash;簡稱ELK進行查看分布式日志系統,但是本文不會進行安裝logstash進行演示,因為只做日志查詢的需求,我們使用ELK的變種EFK即可,filebeat輕量級做日志收集即可,最主要的就是看我們如何進行配置,然后使用kibana進行查詢日志。
安裝完logstash后,解壓在config中新建my-logstash.conf,該配置中注意三大塊,input、filter、output;其中input是作為吸取日志的以.log為后綴的日志文件,filter是過濾配置,不用管,output則是導入到哪個elasticsearch中;配置如下:
1 input {2 file {3 type => "log"4 path => ["/apps/svr/server/*/log.file"]5 start_position => "end"6 ignore_older => 07 codec=> multiline {8 pattern => "^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}"9 negate => true 10 auto_flush_interval => 5 11 what => "previous" 12 } 13 } 14 beats { 15 port => 5044 16 } 17 } 18 output { 19 if [type] == "log" { 20 elasticsearch { 21 hosts => ["http://127.0.0.1:19200"] 22 index => "logstash-%{+YYYY.MM}" 23 #user => es 24 #password => es2018 25 } 26 } 27 }
如果自己動手配置的話,最好自己手動輸入,不要復制粘貼,很有可能會有特殊字符出現導致啟動失敗;啟動命令:./bin/logstah -f my-logstash.conf
? 最終我們就可以這樣使用kibana進行查詢日志的操作了。簡單的基本應用就到此為止了,工作中基礎的應用是沒有問題了;