一. 倒排索引概念


将各个文档中的内容进行分词,形成词条。然后记录词条和数据唯一标识(id)的对应关系形成的产物。
image.png
备注:生成倒排索引中,词条会进行排序,形成树形结构,提高词条的查询速度。

二. ElasticSearch入门


1. ES存储和查询原理

image.png

2. Elastic Search概念

2.1 概念

  • es是基于lucene的搜索服务器;
  • 是一个分布式,高扩展,高实时的搜索与数据分析引擎;
  • 基于Restful web接口;
  • 是Java语言开发,是apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎;
  • 官网:https://www.elactic.co/

2.2 应用场景:

  • 海量数据的查询
  • 日志数据的分析
  • 实时数据的分析

    2.3 Elastic search与MySQL的区别:

  • MySQL有事务性,ES没有事务性,所以,ES当你删除了数据是无法恢复的。

  • ES没有物理外键的特性,如果数据的强一致性要求较高,那么慎用。

总之:ES和MySQL分工不同,MySQL负责储存数据,ES负责搜索数据。

image.png

3. ElasticSearch和kibana安装


Centos7环境安装ElasticSearch

CentOS 7环境安装kibana

4. ElasticSearch核心概念

  • 索引(index):ES存储数据的地方,可以理解成关系数据库中的数据库概念。
  • 映射(mapping):mapping定义了每个字段的类型、字段所使用的分词器等。相当于关系型数据库中的表结构。
  • 文档(document):ES中的最小数据单元,常以json格式显示。一个document相当于关系型数据库中的一行数据。
  • 倒排索引:一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,对应一个包含它的文档id列表。

三. IK分词器


概念:将一段文本,按照一定逻辑,分析成多个词语的一种工具。
IK分词器安装

四. spring boot整合ES

4.1 引入maven坐标

  1. <!-- 引入es -->
  2. <dependency>
  3. <groupId>org.elasticsearch</groupId>
  4. <artifactId>elasticsearch</artifactId>
  5. <version>7.9.2</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.elasticsearch.client</groupId>
  9. <artifactId>elasticsearch-rest-high-level-client</artifactId>
  10. <version>7.9.2</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.elasticsearch.client</groupId>
  14. <artifactId>elasticsearch-rest-client</artifactId>
  15. <version>7.9.2</version>
  16. </dependency>

4.2 将ES托管spring boot

  1. @Configuration
  2. public class ESConfig {
  3. @Bean
  4. public RestHighLevelClient client(){
  5. return new RestHighLevelClient(RestClient.builder(
  6. new HttpHost(
  7. "192.168.233.128",
  8. 9200,
  9. "http"
  10. )
  11. ));
  12. }
  13. }

备注:可以专门设一个config包,专门用来放置配置类。需要使用client对象只需要:

  1. @Autowired
  2. private RestHighLevelClient client;

即可。

五. ES基本增删改查操作

首先要创建一个索引还有映射。可以使用Java创建,也可以使用kibana创建,这里使用kinaba创建。

  1. PUT /索引名/_mappings
  2. {
  3. "properties": {
  4. "id":{"type": "integer"},
  5. "title":{"type": "text"},
  6. "money":{"type": "float"},
  7. "num":{"type": "integer"}
  8. }
  9. }

备注:es7.x以前和以后不一样,7.x以后没有type了。

5.1 添加文档

  1. //添加文档
  2. Goods goods = new Goods();
  3. goods.setId(1);
  4. goods.setMoney(666);
  5. goods.setNum(555);
  6. goods.setTitle("iphone手机");
  7. String s = new Gson().toJson(goods);
  8. IndexRequest indexRequest = new IndexRequest("study").id(String.valueOf(goods.getId())).source(s, XContentType.JSON);
  9. IndexResponse index = client.index(indexRequest, RequestOptions.DEFAULT);
  10. System.out.println(index.getId());

5.2 查询文档

  1. GetRequest study = new GetRequest("study", "1");
  2. GetResponse documentFields = client.get(study, RequestOptions.DEFAULT);
  3. System.out.println(documentFields.getSourceAsString());

5.3 删除文档

  1. DeleteRequest study = new DeleteRequest("study", "1");
  2. DeleteResponse delete = client.delete(study, RequestOptions.DEFAULT);
  3. System.out.println(delete.getId());

备注:如若修改文档,id一样,执行添加操作即可覆盖原文档。

六. ES高级操作

6.1 批量操作

  1. //创建bulkrequest对象,整合所有操作
  2. BulkRequest bulkRequest = new BulkRequest();
  3. /*
  4. # 1. 删除1号记录
  5. # 2. 添加6号记录
  6. # 3. 修改3号记录 名称为 “三号”
  7. */
  8. //添加对应操作
  9. //1. 删除1号记录
  10. DeleteRequest deleteRequest = new DeleteRequest("person","1");
  11. bulkRequest.add(deleteRequest);
  12. //2. 添加6号记录
  13. Map map = new HashMap();
  14. map.put("name","六号");
  15. IndexRequest indexRequest = new IndexRequest("person").id("6").source(map);
  16. bulkRequest.add(indexRequest);
  17. Map map2 = new HashMap();
  18. map2.put("name","三号");
  19. //3. 修改3号记录 名称为 “三号”
  20. UpdateRequest updateReqeust = new UpdateRequest("person","3").doc(map2);
  21. bulkRequest.add(updateReqeust);
  22. //执行批量操作
  23. BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
  24. RestStatus status = response.status();
  25. System.out.println(status);

6.2 批量导入

  1. //1.查询所有数据,mysql
  2. List<Goods> goodsList = goodsMapper.findAll();
  3. //System.out.println(goodsList.size());
  4. //2.bulk导入
  5. BulkRequest bulkRequest = new BulkRequest();
  6. //2.1 循环goodsList,创建IndexRequest添加数据
  7. for (Goods goods : goodsList) {
  8. //2.2 设置spec规格信息 Map的数据 specStr:{}
  9. //goods.setSpec(JSON.parseObject(goods.getSpecStr(),Map.class));
  10. String specStr = goods.getSpecStr();
  11. //将json格式字符串转为Map集合
  12. Map map = JSON.parseObject(specStr, Map.class);
  13. //设置spec map
  14. goods.setSpec(map);
  15. //将goods对象转换为json字符串
  16. String data = JSON.toJSONString(goods);//map --> {}
  17. IndexRequest indexRequest = new IndexRequest("goods");
  18. indexRequest.id(goods.getId()+"").source(data, XContentType.JSON);
  19. bulkRequest.add(indexRequest);
  20. }
  21. BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
  22. System.out.println(response.status());

6.3 matchAll查询

matchAll查询:查询所有文档

  1. /**
  2. * 查询所有
  3. * 1. matchAll
  4. * 2. 将查询结果封装为Goods对象,装载到List中
  5. * 3. 分页。默认显示10条
  6. */
  7. @Test
  8. public void testMatchAll() throws IOException {
  9. //2. 构建查询请求对象,指定查询的索引名称
  10. SearchRequest searchRequest = new SearchRequest("goods");
  11. //4. 创建查询条件构建器SearchSourceBuilder
  12. SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
  13. //6. 查询条件
  14. QueryBuilder query = QueryBuilders.matchAllQuery();//查询所有文档
  15. //5. 指定查询条件
  16. sourceBuilder.query(query);
  17. //3. 添加查询条件构建器 SearchSourceBuilder
  18. searchRequest.source(sourceBuilder);
  19. // 8 . 添加分页信息
  20. sourceBuilder.from(0);
  21. sourceBuilder.size(100);
  22. //1. 查询,获取查询结果
  23. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  24. //7. 获取命中对象 SearchHits
  25. SearchHits searchHits = searchResponse.getHits();
  26. //7.1 获取总记录数
  27. long value = searchHits.getTotalHits().value;
  28. System.out.println("总记录数:"+value);
  29. List<Goods> goodsList = new ArrayList<>();
  30. //7.2 获取Hits数据 数组
  31. SearchHit[] hits = searchHits.getHits();
  32. for (SearchHit hit : hits) {
  33. //获取json字符串格式的数据
  34. String sourceAsString = hit.getSourceAsString();
  35. //转为java对象
  36. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  37. goodsList.add(goods);
  38. }
  39. for (Goods goods : goodsList) {
  40. System.out.println(goods);
  41. }
  42. }

6.4 term查询

term查询:不会对查询条件进行分词。

  1. /**
  2. * termQuery:词条查询
  3. */
  4. @Test
  5. public void testTermQuery() throws IOException {
  6. SearchRequest searchRequest = new SearchRequest("goods");
  7. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  8. QueryBuilder query = QueryBuilders.termQuery("title","华为");//term词条查询
  9. sourceBulider.query(query);
  10. searchRequest.source(sourceBulider);
  11. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  12. SearchHits searchHits = searchResponse.getHits();
  13. //获取记录数
  14. long value = searchHits.getTotalHits().value;
  15. System.out.println("总记录数:"+value);
  16. List<Goods> goodsList = new ArrayList<>();
  17. SearchHit[] hits = searchHits.getHits();
  18. for (SearchHit hit : hits) {
  19. String sourceAsString = hit.getSourceAsString();
  20. //转为java
  21. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  22. goodsList.add(goods);
  23. }
  24. for (Goods goods : goodsList) {
  25. System.out.println(goods);
  26. }
  27. }

6.5 match查询

match查询:
• 会对查询条件进行分词。
• 然后将分词后的查询条件和词条进行等值匹配
• 默认取并集(OR)

  1. /**
  2. * matchQuery:词条分词查询
  3. */
  4. @Test
  5. public void testMatchQuery() throws IOException {
  6. SearchRequest searchRequest = new SearchRequest("goods");
  7. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  8. MatchQueryBuilder query = QueryBuilders.matchQuery("title", "华为手机");
  9. query.operator(Operator.AND);//求并集
  10. sourceBulider.query(query);
  11. searchRequest.source(sourceBulider);
  12. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  13. SearchHits searchHits = searchResponse.getHits();
  14. //获取记录数
  15. long value = searchHits.getTotalHits().value;
  16. System.out.println("总记录数:"+value);
  17. List<Goods> goodsList = new ArrayList<>();
  18. SearchHit[] hits = searchHits.getHits();
  19. for (SearchHit hit : hits) {
  20. String sourceAsString = hit.getSourceAsString();
  21. //转为java
  22. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  23. goodsList.add(goods);
  24. }
  25. for (Goods goods : goodsList) {
  26. System.out.println(goods);
  27. }
  28. }

6.6 模糊查询

  • wildcard查询:会对查询条件进行分词。还可以使用通配符 ?(任意单个字符) 和 * (0个或多个字符)
  • regexp查询:正则查询
  • prefix查询:前缀查询 ```java /**
    • 模糊查询:WildcardQuery */ @Test public void testWildcardQuery() throws IOException {
  1. SearchRequest searchRequest = new SearchRequest("goods");
  2. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  3. WildcardQueryBuilder query = QueryBuilders.wildcardQuery("title", "华*");
  4. sourceBulider.query(query);
  5. searchRequest.source(sourceBulider);
  6. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  7. SearchHits searchHits = searchResponse.getHits();
  8. //获取记录数
  9. long value = searchHits.getTotalHits().value;
  10. System.out.println("总记录数:"+value);
  11. List<Goods> goodsList = new ArrayList<>();
  12. SearchHit[] hits = searchHits.getHits();
  13. for (SearchHit hit : hits) {
  14. String sourceAsString = hit.getSourceAsString();
  15. //转为java
  16. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  17. goodsList.add(goods);
  18. }
  19. for (Goods goods : goodsList) {
  20. System.out.println(goods);
  21. }
  22. }
  23. /**
  24. * 模糊查询:regexpQuery
  25. */
  26. @Test
  27. public void testRegexpQuery() throws IOException {
  28. SearchRequest searchRequest = new SearchRequest("goods");
  29. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  30. RegexpQueryBuilder query = QueryBuilders.regexpQuery("title", "\\w+(.)*");
  31. sourceBulider.query(query);
  32. searchRequest.source(sourceBulider);
  33. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  34. SearchHits searchHits = searchResponse.getHits();
  35. //获取记录数
  36. long value = searchHits.getTotalHits().value;
  37. System.out.println("总记录数:"+value);
  38. List<Goods> goodsList = new ArrayList<>();
  39. SearchHit[] hits = searchHits.getHits();
  40. for (SearchHit hit : hits) {
  41. String sourceAsString = hit.getSourceAsString();
  42. //转为java
  43. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  44. goodsList.add(goods);
  45. }
  46. for (Goods goods : goodsList) {
  47. System.out.println(goods);
  48. }
  49. }
  50. /**
  51. * 模糊查询:perfixQuery
  52. */
  53. @Test
  54. public void testPrefixQuery() throws IOException {
  55. SearchRequest searchRequest = new SearchRequest("goods");
  56. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  57. PrefixQueryBuilder query = QueryBuilders.prefixQuery("brandName", "三");
  58. sourceBulider.query(query);
  59. searchRequest.source(sourceBulider);
  60. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  61. SearchHits searchHits = searchResponse.getHits();
  62. //获取记录数
  63. long value = searchHits.getTotalHits().value;
  64. System.out.println("总记录数:"+value);
  65. List<Goods> goodsList = new ArrayList<>();
  66. SearchHit[] hits = searchHits.getHits();
  67. for (SearchHit hit : hits) {
  68. String sourceAsString = hit.getSourceAsString();
  69. //转为java
  70. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  71. goodsList.add(goods);
  72. }
  73. for (Goods goods : goodsList) {
  74. System.out.println(goods);
  75. }
  76. }
  1. <a name="bTgz9"></a>
  2. ## 6.7 范围查询
  3. range 范围查询:查找指定字段在指定范围内包含值
  4. ```java
  5. /**
  6. * 1. 范围查询:rangeQuery
  7. * 2. 排序
  8. */
  9. @Test
  10. public void testRangeQuery() throws IOException {
  11. SearchRequest searchRequest = new SearchRequest("goods");
  12. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  13. //范围查询
  14. RangeQueryBuilder query = QueryBuilders.rangeQuery("price");
  15. //指定下限
  16. query.gte(2000);
  17. //指定上限
  18. query.lte(3000);
  19. sourceBulider.query(query);
  20. //排序
  21. sourceBulider.sort("price", SortOrder.DESC);
  22. searchRequest.source(sourceBulider);
  23. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  24. SearchHits searchHits = searchResponse.getHits();
  25. //获取记录数
  26. long value = searchHits.getTotalHits().value;
  27. System.out.println("总记录数:"+value);
  28. List<Goods> goodsList = new ArrayList<>();
  29. SearchHit[] hits = searchHits.getHits();
  30. for (SearchHit hit : hits) {
  31. String sourceAsString = hit.getSourceAsString();
  32. //转为java
  33. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  34. goodsList.add(goods);
  35. }
  36. for (Goods goods : goodsList) {
  37. System.out.println(goods);
  38. }
  39. }

6.8 queryString查询

queryString:
• 会对查询条件进行分词。
• 然后将分词后的查询条件和词条进行等值匹配
• 默认取并集(OR)
• 可以指定多个查询字段

  1. /**
  2. * queryString
  3. */
  4. @Test
  5. public void testQueryStringQuery() throws IOException {
  6. SearchRequest searchRequest = new SearchRequest("goods");
  7. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  8. //queryString
  9. QueryStringQueryBuilder query = QueryBuilders.queryStringQuery("华为手机").field("title").field("categoryName").field("brandName").defaultOperator(Operator.AND);
  10. sourceBulider.query(query);
  11. searchRequest.source(sourceBulider);
  12. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  13. SearchHits searchHits = searchResponse.getHits();
  14. //获取记录数
  15. long value = searchHits.getTotalHits().value;
  16. System.out.println("总记录数:"+value);
  17. List<Goods> goodsList = new ArrayList<>();
  18. SearchHit[] hits = searchHits.getHits();
  19. for (SearchHit hit : hits) {
  20. String sourceAsString = hit.getSourceAsString();
  21. //转为java
  22. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  23. goodsList.add(goods);
  24. }
  25. for (Goods goods : goodsList) {
  26. System.out.println(goods);
  27. }
  28. }

6.9 布尔查询

boolQuery:对多个查询条件连接。连接方式:
• must(and):条件必须成立
• must_not(not):条件必须不成立
• should(or):条件可以成立
• filter:条件必须成立,性能比must高。不会计算得分

  1. /**
  2. * 布尔查询:boolQuery
  3. * 1. 查询品牌名称为:华为
  4. * 2. 查询标题包含:手机
  5. * 3. 查询价格在:2000-3000
  6. */
  7. @Test
  8. public void testBoolQuery() throws IOException {
  9. SearchRequest searchRequest = new SearchRequest("goods");
  10. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  11. //1.构建boolQuery
  12. BoolQueryBuilder query = QueryBuilders.boolQuery();
  13. //2.构建各个查询条件
  14. //2.1 查询品牌名称为:华为
  15. QueryBuilder termQuery = QueryBuilders.termQuery("brandName","华为");
  16. query.must(termQuery);
  17. //2.2. 查询标题包含:手机
  18. QueryBuilder matchQuery = QueryBuilders.matchQuery("title","手机");
  19. query.filter(matchQuery);
  20. //2.3 查询价格在:2000-3000
  21. QueryBuilder rangeQuery = QueryBuilders.rangeQuery("price");
  22. ((RangeQueryBuilder) rangeQuery).gte(2000);
  23. ((RangeQueryBuilder) rangeQuery).lte(3000);
  24. query.filter(rangeQuery);
  25. //3.使用boolQuery连接
  26. sourceBulider.query(query);
  27. searchRequest.source(sourceBulider);
  28. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  29. SearchHits searchHits = searchResponse.getHits();
  30. //获取记录数
  31. long value = searchHits.getTotalHits().value;
  32. System.out.println("总记录数:"+value);
  33. List<Goods> goodsList = new ArrayList<>();
  34. SearchHit[] hits = searchHits.getHits();
  35. for (SearchHit hit : hits) {
  36. String sourceAsString = hit.getSourceAsString();
  37. //转为java
  38. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  39. goodsList.add(goods);
  40. }
  41. for (Goods goods : goodsList) {
  42. System.out.println(goods);
  43. }
  44. }

6.10 聚合查询

• 指标聚合:相当于MySQL的聚合函数。max、min、avg、sum等
• 桶聚合:相当于MySQL的 group by 操作。不要对text类型的数据进行分组,会失败

  1. /**
  2. * 聚合查询:桶聚合,分组查询
  3. * 1. 查询title包含手机的数据
  4. * 2. 查询品牌列表
  5. */
  6. @Test
  7. public void testAggQuery() throws IOException {
  8. SearchRequest searchRequest = new SearchRequest("goods");
  9. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  10. // 1. 查询title包含手机的数据
  11. MatchQueryBuilder query = QueryBuilders.matchQuery("title", "手机");
  12. sourceBulider.query(query);
  13. // 2. 查询品牌列表
  14. /*
  15. 参数:
  16. 1. 自定义的名称,将来用于获取数据
  17. 2. 分组的字段
  18. */
  19. AggregationBuilder agg = AggregationBuilders.terms("goods_brands").field("brandName").size(100);
  20. sourceBulider.aggregation(agg);
  21. searchRequest.source(sourceBulider);
  22. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  23. SearchHits searchHits = searchResponse.getHits();
  24. //获取记录数
  25. long value = searchHits.getTotalHits().value;
  26. System.out.println("总记录数:"+value);
  27. List<Goods> goodsList = new ArrayList<>();
  28. SearchHit[] hits = searchHits.getHits();
  29. for (SearchHit hit : hits) {
  30. String sourceAsString = hit.getSourceAsString();
  31. //转为java
  32. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  33. goodsList.add(goods);
  34. }
  35. for (Goods goods : goodsList) {
  36. System.out.println(goods);
  37. }
  38. // 获取聚合结果
  39. Aggregations aggregations = searchResponse.getAggregations();
  40. Map<String, Aggregation> aggregationMap = aggregations.asMap();
  41. //System.out.println(aggregationMap);
  42. Terms goods_brands = (Terms) aggregationMap.get("goods_brands");
  43. List<? extends Terms.Bucket> buckets = goods_brands.getBuckets();
  44. List brands = new ArrayList();
  45. for (Terms.Bucket bucket : buckets) {
  46. Object key = bucket.getKey();
  47. brands.add(key);
  48. }
  49. for (Object brand : brands) {
  50. System.out.println(brand);
  51. }
  52. }

6.11 高亮查询

高亮三要素:高亮字段,前缀,后缀

  1. /**
  2. *
  3. * 高亮查询:
  4. * 1. 设置高亮
  5. * * 高亮字段
  6. * * 前缀
  7. * * 后缀
  8. * 2. 将高亮了的字段数据,替换原有数据
  9. */
  10. @Test
  11. public void testHighLightQuery() throws IOException {
  12. SearchRequest searchRequest = new SearchRequest("goods");
  13. SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
  14. // 1. 查询title包含手机的数据
  15. MatchQueryBuilder query = QueryBuilders.matchQuery("title", "手机");
  16. sourceBulider.query(query);
  17. //设置高亮
  18. HighlightBuilder highlighter = new HighlightBuilder();
  19. //设置三要素
  20. highlighter.field("title");
  21. highlighter.preTags("<font color='red'>");
  22. highlighter.postTags("</font>");
  23. sourceBulider.highlighter(highlighter);
  24. // 2. 查询品牌列表
  25. /*
  26. 参数:
  27. 1. 自定义的名称,将来用于获取数据
  28. 2. 分组的字段
  29. */
  30. AggregationBuilder agg = AggregationBuilders.terms("goods_brands").field("brandName").size(100);
  31. sourceBulider.aggregation(agg);
  32. searchRequest.source(sourceBulider);
  33. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  34. SearchHits searchHits = searchResponse.getHits();
  35. //获取记录数
  36. long value = searchHits.getTotalHits().value;
  37. System.out.println("总记录数:"+value);
  38. List<Goods> goodsList = new ArrayList<>();
  39. SearchHit[] hits = searchHits.getHits();
  40. for (SearchHit hit : hits) {
  41. String sourceAsString = hit.getSourceAsString();
  42. //转为java
  43. Goods goods = JSON.parseObject(sourceAsString, Goods.class);
  44. // 获取高亮结果,替换goods中的title
  45. Map<String, HighlightField> highlightFields = hit.getHighlightFields();
  46. HighlightField HighlightField = highlightFields.get("title");
  47. Text[] fragments = HighlightField.fragments();
  48. //替换
  49. goods.setTitle(fragments[0].toString());
  50. goodsList.add(goods);
  51. }
  52. for (Goods goods : goodsList) {
  53. System.out.println(goods);
  54. }
  55. // 获取聚合结果
  56. Aggregations aggregations = searchResponse.getAggregations();
  57. Map<String, Aggregation> aggregationMap = aggregations.asMap();
  58. //System.out.println(aggregationMap);
  59. Terms goods_brands = (Terms) aggregationMap.get("goods_brands");
  60. List<? extends Terms.Bucket> buckets = goods_brands.getBuckets();
  61. List brands = new ArrayList();
  62. for (Terms.Bucket bucket : buckets) {
  63. Object key = bucket.getKey();
  64. brands.add(key);
  65. }
  66. for (Object brand : brands) {
  67. System.out.println(brand);
  68. }
  69. }

6.12 重建索引&索引别名

重建索引:ElasticSearch的索引一旦创建,只允许添加字段,不允许改变字段。因为改变字段,需要重建倒排索引,影响内部缓存结构,性能太低。那么此时,就需要重建一个新的索引,并将原有索引的数据导入到新索引中。

索引别名:重建索引后,代码中还是使用的老索引在操作ElasticSearch,那么有两种方式解决:
1. 改代码(不推荐);
2. 使用别名(推荐):就是将重建得索引起一个别名,这个别名和原索引一致即可,但是创建别名之前需要删除原索引。

拷贝数据:
POST _reindex
{
“source”:{
“index”:”原索引”
},
“dest”:{
“index”:”新索引”
}
}
起别名:POST 新别名/_alias/原索引

七. ES集群