zoukankan      html  css  js  c++  java
  • java中的ElasticSearch搜索引擎介绍。

    ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    安装

    以windows操作系统和ES0.19.7版本为例:
    ①下载elasticsearch-6.4.1.zip
    ②直接解压至某目录,设置该目录为ES_HOME环境变量
    ③安装JDK,并设置JAVA_HOME环境变量
    ④在windows下,运行 %ES_HOME%inelasticsearch.bat即可运行

    安装插件

    以head插件为例:
    联网时,直接运行%ES_HOME%inplugin --install mobz/elasticsearch-head
    不联网时,下载elasticsearch-head的zipball的master包,然后运行%ES_HOME%inplugin --url file:///[path-to-downloadfile] --install head,其中[path-to-downloadfile]是下载后master包的绝对路径
    安装完成,重启服务,在浏览器打开 http://localhost:9200/_plugin/head/ 即可

     ES工作原理

    当ElasticSearch的节点启动后,它会利用多播(multicast)(或者单播,如果用户更改了配置)寻找集群中的其它节点,并与之建立连接。这个过程如下图所示: 
    这里写图片描述

    官方代码
    1
    RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( 2 new HttpHost("localhost", 9200, "http"))); 3 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 4 searchSourceBuilder.query(QueryBuilders.matchAllQuery()); 5 searchSourceBuilder.aggregation(AggregationBuilders.terms("top_10_states").field("state").size(10)); 6 SearchRequest searchRequest = new SearchRequest(); 7 searchRequest.indices("social-*"); 8 searchRequest.source(searchSourceBuilder); 9 SearchResponse searchResponse = client.search(searchRequest);

    创建索引

     1 /**
     2      * 创建索引
     3      *
     4      * @param index
     5      * @return
     6      */
     7     public boolean createIndex(String index) {
     8         if (!isIndexExist(index)) {
     9             logger.info("index is not exits!");
    10         }
    11         CreateIndexResponse indexresponse = client.admin().indices().prepareCreate(index).execute().actionGet();
    12         logger.info("success to create index " + indexresponse.isAcknowledged());
    13 
    14         return indexresponse.isAcknowledged();
    15     }

    删除索引

     1 /**
     2      * 删除索引
     3      *
     4      * @param index
     5      * @return
     6      */
     7     public boolean deleteIndex(String index) {
     8         if (!isIndexExist(index)) {
     9             logger.info("index is not exits!");
    10         }
    11         DeleteIndexResponse dResponse = client.admin().indices().prepareDelete(index).execute().actionGet();
    12         if (dResponse.isAcknowledged()) {
    13             logger.info("delete index " + index + "  successfully!");
    14         } else {
    15             logger.info("fail to delete index " + index);
    16         }
    17         return dResponse.isAcknowledged();
    18     }

    判断

     1 /**
     2      * 判断索引是否存在
     3      *
     4      * @param index
     5      * @return
     6      */
     7     public boolean isIndexExist(String index) {
     8         IndicesExistsResponse inExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(index)).actionGet();
     9         if (inExistsResponse.isExists()) {
    10             logger.info("index [" + index + "] is exist!");
    11         } else {
    12             logger.info("index [" + index + "] is not exist!");
    13         }
    14         return inExistsResponse.isExists();
    15     }
      1  /**
      2      * 通过ID获取数据
      3      *
      4      * @param index  索引,类似数据库
      5      * @param type   类型,类似表
      6      * @param id     数据ID
      7      * @param fields 需要显示的字段,逗号分隔(缺省为全部字段)
      8      * @return
      9      */
     10     public Map<String, Object> searchDataById(String index, String type, String id, String fields) {
     11         GetRequestBuilder getRequestBuilder = client.prepareGet(index, type, id);
     12         if (StringUtils.isNotEmpty(fields)) {
     13             getRequestBuilder.setFetchSource(fields.split(","), null);
     14         }
     15         GetResponse getResponse =  getRequestBuilder.execute().actionGet();
     16         return getResponse.getSource();
     17     }
     18 
     19     /**
     20      * 使用分词查询
     21      *
     22      * @param index    索引名称
     23      * @param type     类型名称,可传入多个type逗号分隔
     24      * @param fields   需要显示的字段,逗号分隔(缺省为全部字段)
     25      * @param matchStr 过滤条件(xxx=111,aaa=222)
     26      * @return
     27      */
     28     public List<Map<String, Object>> searchListData(String index, String type, String fields, String matchStr) {
     29         return searchListData(index, type, 0, 0, null, fields, null, false, null, matchStr);
     30     }
     31 
     32     /**
     33      * 使用分词查询
     34      *
     35      * @param index       索引名称
     36      * @param type        类型名称,可传入多个type逗号分隔
     37      * @param fields      需要显示的字段,逗号分隔(缺省为全部字段)
     38      * @param sortField   排序字段
     39      * @param matchPhrase true 使用,短语精准匹配
     40      * @param matchStr    过滤条件(xxx=111,aaa=222)
     41      * @return
     42      */
     43     public List<Map<String, Object>> searchListData(String index, String type, String fields, String sortField, boolean matchPhrase, String matchStr) {
     44         return searchListData(index, type, 0, 0, null, fields, sortField, matchPhrase, null, matchStr);
     45     }
     46 
     47 
     48     /**
     49      * 使用分词查询
     50      *
     51      * @param index          索引名称
     52      * @param type           类型名称,可传入多个type逗号分隔
     53      * @param size           文档大小限制
     54      * @param fields         需要显示的字段,逗号分隔(缺省为全部字段)
     55      * @param sortField      排序字段
     56      * @param matchPhrase    true 使用,短语精准匹配
     57      * @param highlightField 高亮字段
     58      * @param matchStr       过滤条件(xxx=111,aaa=222)
     59      * @return
     60      */
     61     public List<Map<String, Object>> searchListData(String index, String type, Integer size, String fields, String sortField, boolean matchPhrase, String highlightField, String matchStr) {
     62         return searchListData(index, type, 0, 0, size, fields, sortField, matchPhrase, highlightField, matchStr);
     63     }
     64 
     65 
     66     /**
     67      * 使用分词查询
     68      *
     69      * @param index          索引名称
     70      * @param type           类型名称,可传入多个type逗号分隔
     71      * @param startTime      开始时间
     72      * @param endTime        结束时间
     73      * @param size           文档大小限制
     74      * @param fields         需要显示的字段,逗号分隔(缺省为全部字段)
     75      * @param sortField      排序字段
     76      * @param matchPhrase    true 使用,短语精准匹配
     77      * @param highlightField 高亮字段
     78      * @param matchStr       过滤条件(xxx=111,aaa=222)
     79      * @return
     80      */
     81     public List<Map<String, Object>> searchListData(String index, String type, long startTime, long endTime, Integer size, String fields, String sortField, boolean matchPhrase, String highlightField, String matchStr) {
     82         SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
     83         if (StringUtils.isNotEmpty(type)) {
     84             searchRequestBuilder.setTypes(type.split(","));
     85         }
     86         BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
     87         
     88         if (startTime > 0 && endTime > 0) {
     89             boolQuery.must(QueryBuilders.rangeQuery("processTime")
     90                     .format("epoch_millis")
     91                     .from(startTime)
     92                     .to(endTime)
     93                     .includeLower(true)
     94                     .includeUpper(true));
     95         }
     96 
     97         //搜索的的字段
     98         if (StringUtils.isNotEmpty(matchStr)) {
     99             for (String s : matchStr.split(",")) {
    100                 String[] ss = s.split("=");
    101                 if (ss.length > 1) {
    102                     if (matchPhrase == Boolean.TRUE) {
    103                         boolQuery.must(QueryBuilders.matchPhraseQuery(s.split("=")[0], s.split("=")[1]));
    104                     } else {
    105                         boolQuery.must(QueryBuilders.matchQuery(s.split("=")[0], s.split("=")[1]));
    106                     }
    107                 }
    108             }
    109         }
    110 
    111         // 高亮(xxx=111,aaa=222)
    112         if (StringUtils.isNotEmpty(highlightField)) {
    113             HighlightBuilder highlightBuilder = new HighlightBuilder();
    114 
    115             //highlightBuilder.preTags("<span style='color:red' >");//设置前缀
    116             //highlightBuilder.postTags("</span>");//设置后缀
    117 
    118             // 设置高亮字段
    119             highlightBuilder.field(highlightField);
    120             searchRequestBuilder.highlighter(highlightBuilder);
    121         }
    122         
    123         searchRequestBuilder.setQuery(boolQuery);
    124         
    125         if (StringUtils.isNotEmpty(fields)) {
    126             searchRequestBuilder.setFetchSource(fields.split(","), null);
    127         }
    128         searchRequestBuilder.setFetchSource(true);
    129 
    130         if (StringUtils.isNotEmpty(sortField)) {
    131             searchRequestBuilder.addSort(sortField, SortOrder.DESC);
    132         }
    133 
    134         if (size != null && size > 0) {
    135             searchRequestBuilder.setSize(size);
    136         }
    137 
    138         //打印的内容 可以在 Elasticsearch head 和 Kibana  上执行查询
    139 //        logger.info("
    {}", searchRequestBuilder);
    140 
    141         SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
    142 
    143         long totalHits = searchResponse.getHits().totalHits;
    144         long length = searchResponse.getHits().getHits().length;
    145 
    146 //        logger.info("共查询到[{}]条数据,处理数据条数[{}]", totalHits, length);
    147 
    148         if (searchResponse.status().getStatus() == 200) {
    149             // 解析对象
    150             return setSearchResponse(searchResponse, highlightField);
    151         }
    152         return null;
    153     }
    154 
    155     /**
    156      * 使用分词查询,并分页
    157      *
    158      * @param index          索引名称
    159      * @param type           类型名称,可传入多个type逗号分隔
    160      * @param currentPage    当前页
    161      * @param pageSize       每页显示条数
    162      * @param startTime      开始时间
    163      * @param endTime        结束时间
    164      * @param fields         需要显示的字段,逗号分隔(缺省为全部字段)
    165      * @param sortField      排序字段
    166      * @param matchPhrase    true 使用,短语精准匹配
    167      * @param highlightField 高亮字段
    168      * @param matchStr       过滤条件(xxx=111,aaa=222)
    169      * @return
    170      */
    171     public EsPage searchDataPage(String index, String type, int currentPage, int pageSize, long startTime, long endTime, String fields, String sortField, boolean matchPhrase, String highlightField, String matchStr) {
    172         SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
    173         if (StringUtils.isNotEmpty(type)) {
    174             searchRequestBuilder.setTypes(type.split(","));
    175         }
    176         searchRequestBuilder.setSearchType(SearchType.QUERY_THEN_FETCH);
    177 
    178         // 需要显示的字段,逗号分隔(缺省为全部字段)
    179         if (StringUtils.isNotEmpty(fields)) {
    180             searchRequestBuilder.setFetchSource(fields.split(","), null);
    181         }
    182 
    183         //排序字段
    184         if (StringUtils.isNotEmpty(sortField)) {
    185             searchRequestBuilder.addSort(sortField, SortOrder.DESC);
    186         }
    187 
    188         BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    189 
    190         if (startTime > 0 && endTime > 0) {
    191             boolQuery.must(QueryBuilders.rangeQuery("@timestamp")
    192                     .format("epoch_millis")
    193                     .from(startTime)
    194                     .to(endTime)
    195                     .includeLower(true)
    196                     .includeUpper(true));
    197         }
    198 
    199         // 查询字段
    200         if (StringUtils.isNotEmpty(matchStr)) {
    201             for (String s : matchStr.split(",")) {
    202                 String[] ss = s.split("=");
    203                 if (ss.length > 1) {
    204                     if (matchPhrase == Boolean.TRUE) {
    205                         boolQuery.must(QueryBuilders.matchPhraseQuery(s.split("=")[0], s.split("=")[1]));
    206                     } else {
    207                         boolQuery.must(QueryBuilders.matchQuery(s.split("=")[0], s.split("=")[1]));
    208                     }
    209                 }
    210             }
    211         }
    212 
    213         // 高亮(xxx=111,aaa=222)
    214         if (StringUtils.isNotEmpty(highlightField)) {
    215             HighlightBuilder highlightBuilder = new HighlightBuilder();
    216 
    217             //highlightBuilder.preTags("<span style='color:red' >");//设置前缀
    218             //highlightBuilder.postTags("</span>");//设置后缀
    219 
    220             // 设置高亮字段
    221             highlightBuilder.field(highlightField);
    222             searchRequestBuilder.highlighter(highlightBuilder);
    223         }
    224 
    225         searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
    226         searchRequestBuilder.setQuery(boolQuery);
    227 
    228         // 分页应用
    229         searchRequestBuilder.setFrom(currentPage).setSize(pageSize);
    230 
    231         // 设置是否按查询匹配度排序
    232         searchRequestBuilder.setExplain(true);
    233 
    234         //打印的内容 可以在 Elasticsearch head 和 Kibana  上执行查询
    235 //        logger.info("
    {}", searchRequestBuilder);
    236 
    237         // 执行搜索,返回搜索响应信息
    238         SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
    239 
    240         long totalHits = searchResponse.getHits().totalHits;
    241         long length = searchResponse.getHits().getHits().length;
    242 
    243 //        logger.debug("共查询到[{}]条数据,处理数据条数[{}]", totalHits, length);
    244 
    245         if (searchResponse.status().getStatus() == 200) {
    246             // 解析对象
    247             List<Map<String, Object>> sourceList = setSearchResponse(searchResponse, highlightField);
    248 
    249             return new EsPage(currentPage, pageSize, (int) totalHits, sourceList);
    250         }
    251         return null;
    252     }
    253 
    254     /**
    255      * 高亮结果集 特殊处理
    256      *
    257      * @param searchResponse
    258      * @param highlightField
    259      */
    260     private List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) {
    261         List<Map<String, Object>> sourceList = new ArrayList<Map<String, Object>>();
    262         StringBuffer stringBuffer = new StringBuffer();
    263 
    264         for (SearchHit searchHit : searchResponse.getHits().getHits()) {
    265             searchHit.getSource().put("id", searchHit.getId());
    266 
    267             if (StringUtils.isNotEmpty(highlightField)) {
    268 
    269                 System.out.println("遍历 高亮结果集,覆盖 正常结果集" + searchHit.getSource());
    270                 Text[] text = searchHit.getHighlightFields().get(highlightField).getFragments();
    271 
    272                 if (text != null) {
    273                     for (Text str : text) {
    274                         stringBuffer.append(str.string());
    275                     }
    276                     //遍历 高亮结果集,覆盖 正常结果集
    277                     searchHit.getSource().put(highlightField, stringBuffer.toString());
    278                 }
    279             }
    280             sourceList.add(searchHit.getSource());
    281         }
    282         return sourceList;
    283     }
     
  • 相关阅读:
    【POJ 2259】Team Queue【队列】
    【POJ 2259】Team Queue【队列】
    【HDU 4699】Editor【栈】
    【HDU 4699】Editor【栈】
    【HDU 4699】Editor【栈】
    【POJ 2559】Largest Rectangle in a Histogram【栈】
    数据结构实验之栈八:栈的基本操作
    数据结构实验之栈八:栈的基本操作
    数据结构实验之栈七:出栈序列判定
    数据结构实验之栈七:出栈序列判定
  • 原文地址:https://www.cnblogs.com/fenghh/p/9725007.html
Copyright © 2011-2022 走看看