zoukankan      html  css  js  c++  java
  • elasticsearch-7.2.0 在windows环境的部署应用

    1、下载解压版"elasticsearch-7.2.0-windows-x86_64.zip",解压至"D:serverelasticsearch-7.2.0"目录;

    2、下载“elasticsearch-analysis-ik-7.2.0.zip”,解压至“D:serverelasticsearch-7.2.0pluginselasticsearch-analysis-ik-7.2.0”;

    3、配置“D:serverelasticsearch-7.2.0configelasticsearch.yml”文件:

    # ======================== Elasticsearch Configuration =========================
    #
    # NOTE: Elasticsearch comes with reasonable defaults for most settings.
    #       Before you set out to tweak and tune the configuration, make sure you
    #       understand what are you trying to accomplish and the consequences.
    #
    # The primary way of configuring a node is via this file. This template lists
    # the most important settings you may want to configure for a production cluster.
    #
    # Please consult the documentation for further information on configuration options:
    # https://www.elastic.co/guide/en/elasticsearch/reference/index.html
    #
    # ---------------------------------- Cluster -----------------------------------
    #
    # Use a descriptive name for your cluster:
    #
    #cluster.name: my-application
    #
    # ------------------------------------ Node ------------------------------------
    #
    # Use a descriptive name for the node:
    #
    #node.name: node-1
    #
    # Add custom attributes to the node:
    #
    #node.attr.rack: r1
    #
    # ----------------------------------- Paths ------------------------------------
    #
    # Path to directory where to store the data (separate multiple locations by comma):
    #
    #path.data: /path/to/data
    #
    # Path to log files:
    #
    #path.logs: /path/to/logs
    #
    # ----------------------------------- Memory -----------------------------------
    #
    # Lock the memory on startup:
    #
    bootstrap.memory_lock: true
    #
    # Make sure that the heap size is set to about half the memory available
    # on the system and that the owner of the process is allowed to use this
    # limit.
    #
    # Elasticsearch performs poorly when the system is swapping the memory.
    #
    # ---------------------------------- Network -----------------------------------
    #
    # Set the bind address to a specific IP (IPv4 or IPv6):
    #
    network.host: 0.0.0.0
    #
    # Set a custom port for HTTP:
    #
    http.port: 9200
    #
    # For more information, consult the network module documentation.
    #
    # --------------------------------- Discovery ----------------------------------
    #
    # Pass an initial list of hosts to perform discovery when this node is started:
    # The default list of hosts is ["127.0.0.1", "[::1]"]
    #
    discovery.seed_hosts: ["host1"]
    #
    # Bootstrap the cluster using an initial set of master-eligible nodes:
    #
    cluster.initial_master_nodes: ["node-1"]
    #
    # For more information, consult the discovery and cluster formation module documentation.
    #
    # ---------------------------------- Gateway -----------------------------------
    #
    # Block initial recovery after a full cluster restart until N nodes are started:
    #
    #gateway.recover_after_nodes: 3
    #
    # For more information, consult the gateway module documentation.
    #
    # ---------------------------------- Various -----------------------------------
    #
    # Require explicit names when deleting indices:
    #
    #action.destructive_requires_name: true
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true

    4、启动服务“D:serverelasticsearch-7.2.0inelasticsearch.bat”

    5、下载解压curl-7.65.1-win64-mingw.zip至“D:curl-7.65.1-win64-mingw”,配置系统环境path增加路径“D:curl-7.65.1-win64-mingwin”;

    6、运行dos命令, 执行“curl -help”验证是否配置成功;

    7、在DOS窗口中,设置用户密码:

    D:serverelasticsearch-7.2.0in>elasticsearch-setup-passwords auto

    Changed password for user apm_system
    PASSWORD apm_system = wXP7CnMmpulr70PrhOy9

    Changed password for user kibana
    PASSWORD kibana = 16P4FhGKQjRxTkI3c8KR

    Changed password for user logstash_system
    PASSWORD logstash_system = 1lyczLndTf2xACdJEt7U

    Changed password for user beats_system
    PASSWORD beats_system = jZRMVw05cQD8xxuCEleY

    Changed password for user remote_monitoring_user
    PASSWORD remote_monitoring_user = MR44yUAc046FihQDhO43

    Changed password for user elastic
    PASSWORD elastic = N0AE4qdTZp0l6zJzGNZ1

    记住以上自动生成的密码;

    8、在DOS窗口中,运行以下命令,创建索引并设置分词器,过滤器:

    curl -u elastic:9lHDbltrSSIPmcjexseY -XPUT "http://192.168.1.230:9200/xuetz" -H "Content-Type:application/json" -d "{"settings":{"analysis":{"analyzer":{"myAnalyzer":{"tokenizer":"ik_max_word","char_filter":["html_strip"]}}}}}"

    9、在DOS窗口中,运行以下命令,设置各个field属性对应的解析器:

    curl -u elastic:9lHDbltrSSIPmcjexseY -XPUT "http://192.168.1.230:9200/xuetz/_mapping" -H "Content-Type:application/json" -d "{"properties":{"opName":{"type":"text","analyzer":"myAnalyzer","search_analyzer":"ik_smart"},"brief":{"type":"text","analyzer":"myAnalyzer","search_analyzer":"ik_smart"},"editor":{"type":"text","analyzer":"myAnalyzer","search_analyzer":"ik_smart"},"keywords":{"type":"text","analyzer":"myAnalyzer","search_analyzer":"ik_smart"}}}"

    如一次性返回buckets数量大于10000,需设置search.max_buckets参数:

    curl -u elastic:9lHDbltrSSIPmcjexseY -XPUT "http://192.168.1.230:9200/_cluster/settings" -H "Content-Type:application/json" -d   "{"persistent":{"search.max_buckets":50000}}"

    10、JAVA采用Java High Level REST Client 调用

    10.1  ESBean.java

    package com.xrh.extend.elasticsearch;
    
    public class ESBean implements java.io.Serializable {
    
        /**
         * 
         */
        private static final long serialVersionUID = -8973010685088776452L;
    
        private String id;       //ID
        private String opName;   //标题
        private String opNameHL; //标题-高亮
        private String brief;    //简介
        private String briefHL;  //简介-高亮
        private String keywords; //关键字
        private String keyWordsHL;//关键字-高亮
        private String editor;   //内容
        private String editorHL; //内容-高亮
        private String picUrl;   //封面图
        private String opSite;   //站点
        private String parentId; //所属栏目ID或父级ID
        private String publishDate; //发布时间
        private String tableName; //表名
        
        private float score; //文档评分
        
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getOpName() {
            return opName;
        }
        public void setOpName(String opName) {
            this.opName = opName;
        }
        public String getBrief() {
            return brief;
        }
        public void setBrief(String brief) {
            this.brief = brief;
        }
        public String getKeywords() {
            return keywords;
        }
        public void setKeywords(String keywords) {
            this.keywords = keywords;
        }
        public String getEditor() {
            return editor;
        }
        public void setEditor(String editor) {
            this.editor = editor;
        }
        public String getOpSite() {
            return opSite;
        }
        public void setOpSite(String opSite) {
            this.opSite = opSite;
        }
        public String getParentId() {
            return parentId;
        }
        public void setParentId(String parentId) {
            this.parentId = parentId;
        }
        public String getPublishDate() {
            return publishDate;
        }
        public void setPublishDate(String publishDate) {
            this.publishDate = publishDate;
        }
        public String getTableName() {
            return tableName;
        }
        public void setTableName(String tableName) {
            this.tableName = tableName;
        }
        public String getOpNameHL() {
            if (opNameHL == null){
                return opName;
            }
            return opNameHL;
        }
        public void setOpNameHL(String opNameHL) {
            this.opNameHL = opNameHL;
        }
        public String getBriefHL() {
            if (briefHL == null){
                return brief;
            }
            return briefHL;
        }
        public void setBriefHL(String briefHL) {
            this.briefHL = briefHL;
        }
        public String getKeyWordsHL() {
            if (keyWordsHL == null){
                return keywords;
            }
            return keyWordsHL;
        }
        public void setKeyWordsHL(String keyWordsHL) {
            this.keyWordsHL = keyWordsHL;
        }
        public String getEditorHL() {
            if (editorHL == null){
                return editor;
            }
            return editorHL;
        }
        public void setEditorHL(String editorHL) {
            this.editorHL = editorHL;
        }
        public float getScore() {
            return score;
        }
        public void setScore(float score) {
            this.score = score;
        }
        public String getPicUrl() {
            return picUrl;
        }
        public void setPicUrl(String picUrl) {
            this.picUrl = picUrl;
        }
        
        
    }

    10.2  ESResult.java

    package com.xrh.extend.elasticsearch;
    
    import java.util.List;
    
    public class ESResult {
    
        private List<ESBean> datas;
        private long totalHits;
        
        public List<ESBean> getDatas() {
            return datas;
        }
        public void setDatas(List<ESBean> datas) {
            this.datas = datas;
        }
        public long getTotalHits() {
            return totalHits;
        }
        public void setTotalHits(long totalHits) {
            this.totalHits =totalHits;
        }
        
        
    }

    10.3 ESTool.java

    package com.xrh.extend.elasticsearch;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.logging.Logger;
    
    import org.apache.http.HttpHost;
    import org.apache.http.auth.AuthScope;
    import org.apache.http.auth.UsernamePasswordCredentials;
    import org.apache.http.client.CredentialsProvider;
    import org.apache.http.client.config.RequestConfig.Builder;
    import org.apache.http.impl.client.BasicCredentialsProvider;
    import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
    import org.elasticsearch.action.DocWriteResponse;
    import org.elasticsearch.action.delete.DeleteRequest;
    import org.elasticsearch.action.delete.DeleteResponse;
    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.action.update.UpdateRequest;
    import org.elasticsearch.action.update.UpdateResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestClientBuilder;
    import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
    import org.elasticsearch.client.RestClientBuilder.RequestConfigCallback;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.common.text.Text;
    import org.elasticsearch.common.unit.TimeValue;
    import org.elasticsearch.common.xcontent.XContentBuilder;
    import org.elasticsearch.common.xcontent.XContentFactory;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.rest.RestStatus;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.SearchHits;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
    
    import com.xrh.base.config.DAO_Config;
    import com.xrh.core.util.JsonUtil;
    import com.xrh.core.util.ObjectUtil;
    
    public class ESTool {
    
        private static Logger logger = Logger.getLogger(ESTool.class.getName());
        
        private RestHighLevelClient restClient = null;
    
        public ESTool(){
            
            String hosts = DAO_Config.getConfigValue("es-hosts"); // 集群地址
            String port = DAO_Config.getConfigValue("es-port"); // 使用的端口号
            String schema = DAO_Config.getConfigValue("es-schema"); // 使用的协议
            
            if (ObjectUtil.isNull(hosts)){
                logger.info("ES集群地址不能为空!无法完成初始化.");
                return ;
            }
            
            if (ObjectUtil.isNull(port)){
                logger.info("ES端口后不能为空!无法完成初始化.");
                return ;
            }
            
            if (ObjectUtil.isNull(schema)){
                logger.info("ES协议不能为空!无法完成初始化.");
                return ;
            }
            
            ArrayList<HttpHost> hostList = new ArrayList<>();
            String[] hostStrs = hosts.split(",");
            for (String host : hostStrs) {
                hostList.add(new HttpHost(host, Integer.parseInt(port), schema));
            }
            
            RestClientBuilder builder = RestClient.builder(hostList.toArray(new HttpHost[0]))
                    .setFailureListener(new RestClient.FailureListener() { // 连接失败策略
                        //
                    }).setRequestConfigCallback(new RequestConfigCallback() {
                        @Override
                        public Builder customizeRequestConfig(Builder requestConfigBuilder) {
                            String connectTimeOut = DAO_Config.getConfigValue("es-connectTimeOut");
                            if (!ObjectUtil.isNull(connectTimeOut)){
                                requestConfigBuilder.setConnectTimeout(Integer.parseInt(connectTimeOut));
                            }
                            String socketTimeout = DAO_Config.getConfigValue("es-socketTimeout");
                            if (!ObjectUtil.isNull(socketTimeout)){
                                requestConfigBuilder.setSocketTimeout(Integer.parseInt(socketTimeout));
                            }
                            String connectionRequestTimeout = DAO_Config.getConfigValue("es-connectionRequestTimeout");
                            if (!ObjectUtil.isNull(connectionRequestTimeout)){
                                requestConfigBuilder.setConnectionRequestTimeout(Integer.parseInt(connectionRequestTimeout));
                            }
                            return requestConfigBuilder;
                        }
                    })
                    .setHttpClientConfigCallback(new HttpClientConfigCallback() { // 认证
                        @Override
                        public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                            
                            String maxConnTotal = DAO_Config.getConfigValue("es-maxConnTotal");
                            if (!ObjectUtil.isNull(maxConnTotal)){
                                httpClientBuilder.setMaxConnTotal(Integer.parseInt(maxConnTotal));
                            }
                            
                            String maxConnPerRoute = DAO_Config.getConfigValue("es-maxConnPerRoute");
                            if (!ObjectUtil.isNull(maxConnPerRoute)){
                                httpClientBuilder.setMaxConnTotal(Integer.parseInt(maxConnPerRoute));
                            }
    
                            String userName = DAO_Config.getConfigValue("es-userName");
                            String password = DAO_Config.getConfigValue("es-password");
                            if (ObjectUtil.isNull(userName) || ObjectUtil.isNull(password)){
                                return httpClientBuilder;
                            }else{
                                CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
                                credentialsProvider.setCredentials(AuthScope.ANY,
                                        new UsernamePasswordCredentials(userName, password));
                                return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                            }
                        }
                    });
            
            restClient = new RestHighLevelClient(builder);
        }
        
        /**
         * 生成索引文档(重复则自动更新)
         * @param bean
         * @return
         */
        public boolean doSave(ESBean bean){
            
            if (restClient == null){
                logger.info("系统未配置搜索服务参数,无法完成索引保存操作!");
                return false;
            }
            
            if(bean == null){
                logger.info("bean 对象为空,无法创建索引!");
                return false;
            }
            
            if (ObjectUtil.isNull(bean.getOpSite())){
                logger.info("对象opSite为空,无法创建索引!");
                return false;
            }
            
            if (ObjectUtil.isNull(bean.getTableName())){
                logger.info("对象tableName为空,无法生成文档唯一ID!");
                return false;
            }
            
            if (ObjectUtil.isNull(bean.getId())){
                logger.info("对象id为空,无法生成文档唯一ID!");
                return false;
            }
            
            XContentBuilder builder = getXContentBuilder(bean);
            UpdateRequest request = new UpdateRequest(bean.getOpSite(), 
                        generateId(bean.getTableName(), bean.getId()))
                        .doc(builder)
                        .upsert(builder);//upsert--id不存在时就插入
            try {
                UpdateResponse response = restClient.update(request, RequestOptions.DEFAULT);
                response.forcedRefresh();
                if (response.status().equals(RestStatus.OK) 
                        || response.status().equals(RestStatus.CREATED)){
                    logger.info("索引文档【id="+bean.getId()+" opName="+bean.getOpName()+"】保存成功!");
                    return true;
                }else{
                    logger.info("保存失败,状态="+response.status()+" "+response.toString());
                    return false;
                }
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                return false;
            }
        }
        
        /**
         * 删除索引文档
         * @param site       站点ID
         * @param tableName  表名
         * @param id         主键
         * @return
         */
        public boolean doDelete(String site, String tableName, String id){
            
            if (restClient == null){
                logger.info("系统未配置搜索服务参数,无法完成索引删除操作!");
                return false;
            }
            
            if (ObjectUtil.isNull(site)){
                logger.info("site为空,定位索引!");
                return false;
            }
            
            DeleteRequest request = new DeleteRequest()
                    .index(site)
                    .id(generateId(tableName, id));
            try {
                DeleteResponse deleteResponse = restClient.delete(
                        request, RequestOptions.DEFAULT);
                if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {
                    logger.info("未找到要删除的文档【"+generateId(tableName, id)+"】");
                    return true;
                }
                if (deleteResponse.status().equals(RestStatus.OK)){
                    logger.info("文档【"+generateId(tableName, id)+"】删除成功!");
                    return true;
                }else{
                    logger.info("删除状态="+deleteResponse.status() + " "+deleteResponse.toString());
                    return false;
                }
                
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                return false;
            }
        }
        
        /**
         * 搜索文档
         * @param site            站点ID
         * @param sourceBuilder   searchSourceBuilder
         * @param from            起始位置
         * @param size            获取条数
         * @param highlightFields 高亮属性
         * @return
         */
        public ESResult doSearch(String site, 
                SearchSourceBuilder sourceBuilder,
                int from,
                int size,
                String[] highlightFields){
            
            if (restClient == null){
                logger.info("系统未配置搜索服务参数,无法完成检索操作!");
                return null;
            }
            
            if (ObjectUtil.isNull(site)){
                logger.info("site为空,定位索引!");
                return null;
            }
            
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices(site);
            
            sourceBuilder.from(from); //设置from选项,确定要开始搜索的结果索引。 默认为0。
            sourceBuilder.size(size); //设置大小选项,确定要返回的搜索匹配数。 默认为10。
            String timeout = DAO_Config.getConfigValue("es-timeout"); //搜索超时时间
            if (!ObjectUtil.isNull(timeout)){
                sourceBuilder.timeout(new TimeValue(Integer.parseInt(timeout)));
            }
            
            if (highlightFields != null){
                String preTags = DAO_Config.getConfigValue("es-preTags"); //高亮前缀
                String postTags = DAO_Config.getConfigValue("es-postTags"); //高亮后缀
                HighlightBuilder highlightBuilder = new HighlightBuilder();
                for (String highlightField : highlightFields){
                    HighlightBuilder.Field field = new HighlightBuilder.Field(highlightField);
                    highlightBuilder.field(field);
                }
                if (!ObjectUtil.isNull(preTags) 
                        && !ObjectUtil.isNull(postTags)){
                    highlightBuilder.preTags(preTags);
                    highlightBuilder.postTags(postTags); 
                }
                sourceBuilder.highlighter(highlightBuilder);
            }
            
            searchRequest.source(sourceBuilder);
            
            try {
                SearchResponse response = restClient.search(searchRequest, RequestOptions.DEFAULT);
                logger.info("文档搜索结果 status="+response.status());
                ESResult esResult = new ESResult();
                
                SearchHits searchHits = response.getHits();
                esResult.setTotalHits(searchHits.getTotalHits().value);
                
                List<ESBean> datas = new ArrayList();
                Iterator<SearchHit> iterator = searchHits.iterator();
                while (iterator.hasNext()){
                    SearchHit searchHit = iterator.next();
                    ESBean data = JsonUtil.json2Obj(searchHit.getSourceAsString(), ESBean.class);
                    data.setScore(searchHit.getScore());
                    
                    if (highlightFields != null){
                        Map<String, HighlightField> hlFieldsMap = searchHit.getHighlightFields();
                        
                        for (String highlightField : highlightFields){
                            if (hlFieldsMap.containsKey(highlightField)){
                                HighlightField highlight = hlFieldsMap.get(highlightField);
                                Text[] fragments = highlight.fragments();
                                if (fragments.length > 0){
                                    StringBuffer sb = new StringBuffer();;
                                    for (Text fragment : fragments){
                                        sb.append(fragment.string());
                                    }
                                    if (highlightField.toLowerCase().equals("opname")){
                                        data.setOpNameHL(sb.toString());
                                    } else if (highlightField.toLowerCase().equals("brief")){
                                        data.setBriefHL(sb.toString());
                                    } else if (highlightField.toLowerCase().equals("keywords")){
                                        data.setKeyWordsHL(sb.toString());
                                    } else if (highlightField.toLowerCase().equals("editor")){
                                        data.setEditorHL(fiterHtmlTag(sb.toString()));
                                    } else {
                                        logger.info("highlightField【"+highlightField+"】不在ESBean属性范围!");
                                    }
                                }
                            }
                        }
                    }
                    datas.add(data);
                }
                esResult.setDatas(datas);
                return esResult;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
        
        /**
         * 关闭restClient对象
         */
        public void close(){
            try {
                if (restClient != null){
                    restClient.close();
                    restClient = null;
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        private static String fiterHtmlTag(String html){
            String filterTags = "(?!<(font|/font|em|/em).*?>)<.*?>"; //html不过滤的标签
            if (!ObjectUtil.isNull(filterTags) && !ObjectUtil.isNull(html)){
                return html.replaceAll(filterTags, "");
            }
            return html;
        }
     
        /**
         * 生成索引文档对象
         * @param bean
         * @return
         */
        private XContentBuilder getXContentBuilder(ESBean bean){
            XContentBuilder builder = null;
            try {
                builder = XContentFactory.jsonBuilder().startObject()
                        .field("id", bean.getId())
                        .field("opName", bean.getOpName())
                        .field("brief", bean.getBrief())
                        .field("keywords", bean.getKeywords())
                        .field("editor", bean.getEditor())
                        .field("opSite", bean.getOpSite())
                        .field("parentId", bean.getParentId())
                        .field("picUrl", bean.getPicUrl())
                        .field("publishDate", bean.getPublishDate())
                        .field("tableName", bean.getTableName())
                        .endObject();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return builder;
            
        }
        
        /**
         * 生成文档ID
         * @param tableName  表名
         * @param id         主键
         * @return
         */
        private String generateId(String tableName, String id){
            return tableName + "_" + id;
        }
        
        public static void main(String[] args){
             ESTool esTool = new ESTool();
             
             SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
             sourceBuilder.query(QueryBuilders.boolQuery()
                   .must(QueryBuilders.multiMatchQuery("住房公积金管理中心服务大厅", 
                           "opName", "editor", "brief", "keywords"))     // 自动分词匹配
    //               .must(QueryBuilders.termsQuery("parentId","21","46")) // 全匹配(文本不会进行分词),可一次匹配多个值
    //               .must(QueryBuilders.rangeQuery("publishDate")
    //                       .from("2019-01-01 00:00:00").to("2019-01-31 23:59:59")) //区间搜索
                     );
             
             ESResult result = esTool.doSearch("xuetz", sourceBuilder, 0, 2, 
                   new String[]{"opName", "brief"});
    
             esTool.close();
     
        }
    }
  • 相关阅读:
    向MySql中插入中文时出现乱码
    MySql插入记录时判断
    SuperGridControl 使用小技巧
    Winform开发中常见界面的DevExpress处理操作
    mysql优化之索引建立的规则
    App性能优化浅谈
    AndroidManifest具体解释之Application(有图更好懂)
    算法——递归思想解决排列组合问题
    Windows App开发之集合控件与数据绑定
    table行随鼠标变色
  • 原文地址:https://www.cnblogs.com/101key/p/11168574.html
Copyright © 2011-2022 走看看