elk 单机版 docker 快速安装

Docker Hub官网:https://hub.docker.com/r/sebp/elk/
Docker ELK使用文档:http://elk-docker.readthedocs.io/

Docker至少得分配3GB的内存;
Elasticsearch至少需要单独2G的内存;

  1. # 1. 修改内核参数
  2. vim /etc/sysctl.conf
  3. vm.max_map_count = 655360
  4. vm.swappiness = 1
  5. # 2. 安装
  6. docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 \
  7. -e ES_MIN_MEM=128m \
  8. -e ES_MAX_MEM=1024m \
  9. -v /data/es/plugins/:/opt/elasticsearch/plugins/ \
  10. -it -d --name elk sebp/elk

ik 分词插件

IK分词器github地址: https://github.com/medcl/elasticsearch-analysis-ik

kibana dev tools 常用操作

  1. ######### 查看原数据信息 ##########
  2. # 查看集群的健康状态
  3. GET _cat/health?v
  4. # 查看集群的 index
  5. GET _cat/indices?v
  6. GET _cat/plugins?v
  7. ##### ik 分词测试 ###
  8. GET _analyze
  9. {
  10. "analyzer": "ik_max_word"
  11. , "text": ["学习近平平安归来"]
  12. }
  13. ######### 数据的 PUT, POST, GET ###############
  14. DELETE student
  15. PUT student
  16. {
  17. "mappings": {
  18. "properties": {
  19. "name": {
  20. "type": "keyword"
  21. },
  22. "age": {
  23. "type": "integer"
  24. },
  25. "sex": {
  26. "type": "keyword"
  27. },
  28. "favo": {
  29. "type": "text",
  30. "analyzer": "ik_max_word"
  31. }
  32. }
  33. }
  34. }
  35. # PUT 操作
  36. PUT student/_doc/001
  37. {
  38. "name": "ylb",
  39. "age": "99",
  40. "sex": "男",
  41. "favo": "学习近平"
  42. }
  43. PUT student/_doc/002
  44. {
  45. "name": "y002",
  46. "age": "12",
  47. "sex": "女",
  48. "favo": "吃饭睡觉打豆豆..."
  49. }
  50. PUT student/_doc/003
  51. {
  52. "name": "y003",
  53. "age": "13",
  54. "sex": "女",
  55. "favo": "学习旅游行走"
  56. }
  57. PUT student/_doc/004
  58. {
  59. "name": "y004",
  60. "age": "13",
  61. "sex": "男",
  62. "favo": "学习旅行跑"
  63. }
  64. ### GET 查看 student 中的数据
  65. GET student/_search
  66. # POST 操作
  67. POST student/_doc
  68. {
  69. "name": "p004",
  70. "age": "14",
  71. "sex": "女",
  72. "favo": "敲代码"
  73. }
  74. ######### 检索 ############
  75. # 全文档检索
  76. GET student/_search
  77. #
  78. GET student/_search
  79. {
  80. "query": {
  81. "bool": {
  82. "filter": {
  83. "term": {
  84. "favo": "学习旅行"
  85. }
  86. }
  87. }
  88. }
  89. }
  90. # match: where ... or ...
  91. GET student/_search
  92. {
  93. "query": {
  94. "match": {
  95. "favo": "学习旅行"
  96. }
  97. }
  98. }
  99. # match: where ... and ...
  100. GET student/_search
  101. {
  102. "query": {
  103. "match": {
  104. "favo": {
  105. "query": "学习旅行",
  106. "operator": "and"
  107. }
  108. }
  109. }
  110. }
  111. # 多条件匹配: filter ... must ...
  112. GET student/_search
  113. {
  114. "query": {
  115. "bool": {
  116. "filter": {
  117. "term": {
  118. "sex": "男"
  119. }
  120. },
  121. "must": [
  122. {
  123. "match": {
  124. "favo": "学习"
  125. }
  126. },
  127. {
  128. "match": {
  129. "age": "13"
  130. }
  131. }
  132. ]
  133. }
  134. }
  135. }
  136. # 模糊匹配: fuzzy ,主要用来匹配英文
  137. GET student/_search
  138. {
  139. "query": {
  140. "fuzzy": {
  141. "name": {
  142. "value": "y00"
  143. }
  144. }
  145. },
  146. "from": 0,
  147. "size": 2
  148. }
  149. # 聚合操作: aggs
  150. GET student/_search
  151. {
  152. "aggs": {
  153. "group_by_sex": {
  154. "terms": {
  155. "field": "sex",
  156. "size": 2
  157. }
  158. },
  159. "group_age":{
  160. "max": {
  161. "field": "age"
  162. }
  163. }
  164. }
  165. }
  166. # 分页显示操作: from
  167. ## 显示第0页的2条数据
  168. GET student/_search
  169. {
  170. "from": 0,
  171. "size": 2
  172. }
  173. ## 综合练习 ##
  174. ## 统计 "学习" 有多少人,最大年龄的是多少
  175. GET student/_search
  176. {
  177. "query": {
  178. "bool": {
  179. "filter": {
  180. "term": {
  181. "favo": "学习"
  182. }
  183. },
  184. "must": [
  185. {"match": {
  186. "sex": "男"
  187. }}
  188. ]
  189. }
  190. },
  191. "aggs": {
  192. "group_age": {
  193. "max": {
  194. "field": "age"
  195. }
  196. }
  197. },
  198. "from": 0,
  199. "size": 20
  200. }

ES 7.6 java API

先决条件

  1. ## kibana dev tools 执行如下:
  2. DELETE test01
  3. PUT test01
  4. {
  5. "mappings": {
  6. "properties": {
  7. "name": {
  8. "type": "keyword"
  9. },
  10. "age": {
  11. "type": "integer"
  12. }
  13. }
  14. }
  15. }

es 依赖

  1. <!-- ES 依赖 -->
  2. <dependency>
  3. <groupId>org.elasticsearch.client</groupId>
  4. <artifactId>elasticsearch-rest-client</artifactId>
  5. <version>7.6.0</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.elasticsearch.client</groupId>
  9. <artifactId>elasticsearch-rest-high-level-client</artifactId>
  10. <version>7.6.0</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.elasticsearch</groupId>
  14. <artifactId>elasticsearch</artifactId>
  15. <version>7.6.0</version>
  16. </dependency>
  17. <!-- maven 打包依赖 -->
  18. <build>
  19. <plugins>
  20. <plugin>
  21. <groupId>org.apache.maven.plugins</groupId>
  22. <artifactId>maven-shade-plugin</artifactId>
  23. <version>3.1.0</version>
  24. <executions>
  25. <execution>
  26. <phase>package</phase>
  27. <goals><goal>shade</goal></goals>
  28. <configuration>
  29. <relocations>
  30. <relocation>
  31. <pattern>org.apache.http</pattern>
  32. <shadedPattern>hidden.org.apache.http</shadedPattern>
  33. </relocation>
  34. <relocation>
  35. <pattern>org.apache.logging</pattern>
  36. <shadedPattern>hidden.org.apache.logging</shadedPattern>
  37. </relocation>
  38. <relocation>
  39. <pattern>org.apache.commons.codec</pattern>
  40. <shadedPattern>hidden.org.apache.commons.codec</shadedPattern>
  41. </relocation>
  42. <relocation>
  43. <pattern>org.apache.commons.logging</pattern>
  44. <shadedPattern>hidden.org.apache.commons.logging</shadedPattern>
  45. </relocation>
  46. </relocations>
  47. </configuration>
  48. </execution>
  49. </executions>
  50. </plugin>
  51. </plugins>
  52. </build>

Java API 操作

官方文档: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-index.html

Put (Index)

  1. /**
  2. * 向Index 中 put 数据
  3. * @param hostname
  4. * @param port
  5. * @param scheme
  6. * @param index
  7. * @throws IOException
  8. */
  9. public static void PutIndex(String hostname, Integer port, String scheme, String index) throws IOException {
  10. // 创建 client
  11. RestHighLevelClient client = new RestHighLevelClient(
  12. RestClient.builder(
  13. new HttpHost(hostname,port,scheme)
  14. ));
  15. // ---------------- 方法4 --------------------
  16. // IndexRequest indexRequest = new IndexRequest(index)
  17. // .id("005")
  18. // .source("name", "qq003",
  19. // "age", 24
  20. // );
  21. // ---------------- 方法3 ----------------------------
  22. // XContentBuilder builder = XContentFactory.jsonBuilder();
  23. // builder.startObject();
  24. // {
  25. // builder.field("name", "W003");
  26. // builder.field("age", 23);
  27. // }
  28. // builder.endObject();
  29. // IndexRequest indexRequest = new IndexRequest(index)
  30. // .id("004").source(builder);
  31. // ---------------- 方法2 ----------------------------
  32. // Map<String, Object> jsonMap = new HashMap<>();
  33. // jsonMap.put("name", "W001");
  34. // jsonMap.put("age", 22);
  35. //
  36. // IndexRequest indexRequest = new IndexRequest(index)
  37. // .id("002").source(jsonMap);
  38. // ----------------- 方法1 ----------------------
  39. IndexRequest request = new IndexRequest(index);
  40. request.id("003");
  41. String jsonString = "{\n" +
  42. " \"name\": \"N001\",\n" +
  43. " \"age\": \"12\"\n" +
  44. "}";
  45. IndexRequest indexRequest = request.source(jsonString, XContentType.JSON);
  46. // 执行
  47. client.index(indexRequest,RequestOptions.DEFAULT);
  48. // close client
  49. client.close();
  50. }

Bulk

  1. /**
  2. *
  3. * @param hostname
  4. * @param port
  5. * @param scheme
  6. * @param index
  7. * @throws IOException
  8. */
  9. public static void Bulk(String hostname, Integer port, String scheme, String index) throws IOException {
  10. List<test01> list = new ArrayList<test01>();
  11. list.add(new test01(010,"aa01",111));
  12. list.add(new test01(011,"bb02", 222));
  13. // 创建 client
  14. RestHighLevelClient client = new RestHighLevelClient(
  15. RestClient.builder(new HttpHost(hostname, port, scheme))
  16. );
  17. // bulk request
  18. BulkRequest bulkRequest = new BulkRequest();
  19. for (test01 test01 : list) {
  20. // 将 test01对象 转为 json 对象
  21. String jsonString = JSON.toJSONString(test01);
  22. bulkRequest.add(new IndexRequest(index).id(test01.getId().toString()).source(jsonString,XContentType.JSON));
  23. }
  24. // 执行
  25. client.bulk(bulkRequest,RequestOptions.DEFAULT);
  26. // client close
  27. client.close();
  28. }

Get ( index for id)

  1. /**
  2. * @function Get Index 中的 某个 id 的数据
  3. * @param hostname
  4. * @param port
  5. * @param scheme
  6. * @param index
  7. * @return
  8. * @throws IOException
  9. */
  10. public static GetResponse GetIndex(String hostname, Integer port, String scheme, String index) throws IOException {
  11. // 创建 client
  12. final RestHighLevelClient client = new RestHighLevelClient(
  13. RestClient.builder(new HttpHost(hostname, port, scheme)));
  14. GetRequest getRequest = new GetRequest(
  15. index,
  16. "003");
  17. // 执行
  18. GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
  19. // client close
  20. client.close();
  21. return getResponse;
  22. }

search ( 高级搜索 )

dev tools 执行如下:

  1. # 统计 "学习" 有多少人,最大年龄的是多少
  2. GET student/_search
  3. {
  4. "query": {
  5. "bool": {
  6. "filter": {
  7. "term": {
  8. "favo": "学习"
  9. }
  10. },
  11. "must": [
  12. {"match": {
  13. "sex": "男"
  14. }}
  15. ]
  16. }
  17. },
  18. "aggs": {
  19. "count_by_name": {
  20. "terms": {
  21. "field": "name",
  22. "size": 10
  23. }
  24. },
  25. "group_age": {
  26. "max": {
  27. "field": "age"
  28. }
  29. }
  30. },
  31. "from": 0,
  32. "size": 20
  33. }

java API 代码

  1. public static void Search(String hostname, Integer port, String scheme, String index) throws IOException {
  2. // 创建 client
  3. final RestHighLevelClient client = new RestHighLevelClient(
  4. RestClient.builder(new HttpHost(hostname, port, scheme)));
  5. final SearchRequest searchRequest = new SearchRequest(index);
  6. final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  7. // 查询条件
  8. // query
  9. BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
  10. // filter
  11. boolQueryBuilder.filter(new TermQueryBuilder("favo","学习"));
  12. // must
  13. boolQueryBuilder.must(new MatchQueryBuilder("sex", "男"));
  14. searchSourceBuilder.query(boolQueryBuilder);
  15. // aggs
  16. TermsAggregationBuilder groupName = new TermsAggregationBuilder("groupName", ValueType.LONG);
  17. groupName.field("name");
  18. groupName.size(20);
  19. searchSourceBuilder.aggregation(groupName);
  20. MaxAggregationBuilder maxAge = new MaxAggregationBuilder("maxAge");
  21. maxAge.field("age");
  22. searchSourceBuilder.aggregation(maxAge);
  23. // 分页
  24. searchSourceBuilder.from(0);
  25. searchSourceBuilder.size(2);
  26. searchRequest.source(searchSourceBuilder);
  27. // 执行
  28. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  29. // 打印结果
  30. System.out.println("---------- 原始数据 -------------");
  31. System.out.println(searchResponse);
  32. TotalHits hits = searchResponse.getHits().getTotalHits();
  33. float maxScore = searchResponse.getHits().getMaxScore();
  34. final SearchHit[] searchHits = searchResponse.getHits().getHits();
  35. // 遍历 hits 的数据
  36. System.out.println("----------- 遍历 hits 的数据 ----------------");
  37. for (SearchHit searchHit : searchHits) {
  38. final Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  39. final JSONObject jsonObject = new JSONObject();
  40. for (Object o: sourceAsMap.keySet()) {
  41. jsonObject.put((String) o, sourceAsMap.get(o));
  42. }
  43. jsonObject.put("index",searchHit.getIndex());
  44. jsonObject.put("id", searchHit.getId());
  45. System.out.println(jsonObject.toString());
  46. }
  47. // 解析聚合数据
  48. Aggregations aggregation = searchResponse.getAggregations();
  49. // 获取最大年龄
  50. // Aggregation ma = aggregation.get("maxAge");
  51. // System.out.println(ma); // 先看下 ma 的类型, 下面再定义类型
  52. ParsedMax MaxAge = aggregation.get("maxAge");
  53. // 获取班级分组
  54. System.out.println("---- 班级分组 ----");
  55. ParsedStringTerms groupN = aggregation.get("groupName");
  56. List<? extends Terms.Bucket> buckets = groupN.getBuckets();
  57. for (Terms.Bucket bucket : buckets) {
  58. System.out.println(bucket.getKey() + " ---> " + bucket.getDocCount());
  59. }
  60. System.out.printf("共查询出 %s 条数据,\n最高分数 %s ,\n最大年龄为 %s ,\n",
  61. hits,maxScore,MaxAge.getValue());
  62. // client close
  63. client.close();
  64. }

问题

1. The mapping definition cannot be nested under a type [_doc]

在 ES6.X 中执行正常, 在7.x 中 有错误。

  1. PUT student
  2. {
  3. "mappings": {
  4. "_doc": {
  5. "properties": {
  6. "name": {
  7. "type": "keyword"
  8. },
  9. "age": {
  10. "type": "integer"
  11. },
  12. "sex": {
  13. "type": "keyword"
  14. },
  15. "favo": {
  16. "type": "text",
  17. "analyzer": "ik_max_word"
  18. }
  19. }
  20. }
  21. }
  22. }

报错如下:

  1. {
  2. "error" : {
  3. "root_cause" : [
  4. {
  5. "type" : "illegal_argument_exception",
  6. "reason" : "The mapping definition cannot be nested under a type [_doc] unless include_type_name is set to true."
  7. }
  8. ],
  9. "type" : "illegal_argument_exception",
  10. "reason" : "The mapping definition cannot be nested under a type [_doc] unless include_type_name is set to true."
  11. },
  12. "status" : 400
  13. }

解决方案:
默认不在支持指定索引类型。
尽管官方说, include_type_name is set to true , 但是这里不建议使用, 因为 ES8.x 中将移除。
_doc 类型 去掉即可。