ElasticSearch

简介

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

安装

1、新版本要求至少jdk1.8以上。
2、支持tar、zip、rpm等多种安装方式。
在windows下开发建议使用ZIP安装方式。
3、支持docker方式安装
详细参见:https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html
下载ES: Elasticsearch 6.2.1
https://www.elastic.co/downloads/past-releases
解压 elasticsearch-6.2.1.zip

安装包结构

bin:脚本目录,包括:启动、停止等可执行脚本
config:配置文件目录
data:索引目录,存放索引文件的地方
logs:日志目录
modules:模块目录,包括了es的功能模块
plugins :插件目录,es支持插件机制

配置文件

(1)elasticsearch.yml : 用于配置Elasticsearch运行参数

cluster.name: plxc
node.name: node_1
network.host: 0.0.0.0
http.port: 9200 #设置对外服务的http端口
transport.tcp.port: 9300  #集群结点之间通信端口
node.master: true  #是否有资格被选举成为master结点
node.data: true # 指定该节点是否存储索引数据
#discovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301", "0.0.0.0:9302"] #设置集群中master节点的初始列表
discovery.zen.ping.timeout: 3s #设置ES自动发现节点连接超时的时间
discovery.zen.minimum_master_nodes: 1  #主结点数量的最少值
bootstrap.memory_lock: false
node.max_local_storage_nodes: 1
path.data: D:\ElasticSearch\elasticsearch‐6.2.1\data
path.logs: D:\ElasticSearch\elasticsearch‐6.2.1\logs
http.cors.enabled: true  #开启cors跨域访问支持
http.cors.allow‐origin: /.*/  

(2)jvm.options : 用于配置Elasticsearch JVM设置

设置最小及最大的JVM堆内存大小:
在jvm.options中设置 -Xms和-Xmx:
1) 两个值设置为相等
2) 将 Xmx 设置为不超过物理内存的一半

(3)log4j2.properties: 用于配置Elasticsearch日志

日志文件设置,ES使用log4j,注意日志级别的配置。

系统配置

在linux上根据系统资源情况,可将每个进程最多允许打开的文件数设置大些。

sudo su
ulimit ‐n 65536
su elasticsearch  # 切换elasticsearch用户
vim /etc/security/limits.conf  # 添加如下行
elasticsearch ‐ nofile 65536

图形界面head插件

head插件是ES的一个可视化管理插件,用来监视ES的状态,并通过head客户端和ES服务进行交互,比如创建映射、创建索引等,head的项目地址在https://github.com/mobz/elasticsearch-head
从ES6.0开始,head插件支持使得node.js运行。
(1)安装node.js
(2)下载,运行,默认端口9100

git clone git://github.com/mobz/elasticsearch-head.git 
cd elasticsearch-head 
npm install 
npm run start

REST相关API

索引库_创建表

同一个索引库中存储了相同类型的文档。它就相当于MySQL中的表,或相当于Mongodb中的集合。

put http://localhost:9200/plxc
{
    "settings":{
	    "index":{
		    "number_of_shards":1,
		    "number_of_replicas":0
	    }
    }
}

number_of_shards:设置分片的数量,在集群中通常设置多个分片
number_of_replicas:设置副本的数量,设置副本是为了提高ES的高可靠性

映射_创建表字段

注意:6.0之前的版本有type(类型)概念,type相当于关系数据库的表,ES官方将在ES9.0版本中彻底删除type。

post  http://localhost:9200/plxc/doc/_mapping
{
    "properties": {
	    "name": {
	   	 	"type": "text"
	    },
	    "description": {
	   		 "type": "text"
	    },
	    "studymodel": {
	    	"type": "keyword"
	    }
    }
}

文档_记录

(1)创建记录
如果不指定id值ES会自动生成ID

put 或Post http://localhost:9200/plxc/doc/1023e58161bcf7f40161bcf8b77c3123 
{
    "name":"Bootstrap开发框架",
    "description":"Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。",
    "studymodel":"101011"
}

(2)搜索指定主键记录

get http://localhost:9200/plxc/doc/1023e58161bcf7f40161bcf8b77c3123

(3)查询所有记录

get http://localhost:9200/plxc/doc/_search

(4)查询名称中包括spring 关键字的的记录

get http://localhost:9200/plxc/doc/_search?q=name:bootstrap

IK分词器

ik分词器有两种分词模式:ik_max_word和ik_smart模式。
1、ik_max_word
会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。
2、ik_smart
会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。

检查分词器

post  localhost:9200/_analyze
{
	"text":"测试分词器"
}

结果将测试这个分开,表示当前未使用到中文分词器

下载、安装

Github地址:https://github.com/medcl/elasticsearch-analysis-ik
解压,并将解压的文件拷贝到ES安装目录的plugins下的ik目录下

测试

post  localhost:9200/_analyze
{
	"text":"测试分词器",
	"analyzer":"ik_max_word"
}

自定义分词

iK分词器自带一个main.dic的文件,此文件为词库文件。
在上边的目录中新建一个my.dic文件(注意文件格式为utf-8(不要选择utf-8 BOM))其中每行为指定词汇。
修改IKAnalyzer.cfg.xml配置文件,ext_dict指定值为my.dic,重启ES。

示例

post:http://localhost:9200/plxc/doc/_mapping
{
    "properties": {
	    "description": {
		    "type": "text",
		    "analyzer": "ik_max_word",
		    "search_analyzer": "ik_smart"
	    },
	    "name": {
		    "type": "text",
		    "analyzer": "ik_max_word",
		    "search_analyzer": "ik_smart"
	    },
	    "pic":{
		    "type":"text",
		    "index":false
	    },
	    "price": {
	  	 	 "type": "float"
	    },
	    "studymodel": {
	   		 "type": "keyword"
	    },
	    "timestamp": {
		    "type": "date",
		    "format": "yyyy‐MM‐dd HH:mm:ss||yyyy‐MM‐dd||epoch_millis"
	    }
    }
}

字符串text

text:
通过analyzer属性指定分词器,指在索引和搜索都使用。
通过search_analyzer属性指定分词器,单独想定义搜索时使用的分词器。
通过index属性指定是否索引,商品图片地址只被用来展示图片,不进行搜索图片,此时可以将index设置为false。

字符串keyword

keyword:
通常搜索keyword是按照整体搜索,所以创建keyword字段的索引时是不进行分词的。
比如:邮政编码、手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。

映射调整方案

添加字段并赋值

(1)添加字段

PUT http://localhost:9200/plxc/doc/_mapping
{
     "properties": {
        "TimeFormat": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss"
        }
    }
}

(2)赋值工具类示例

public static void updateHourByScroll(String Type) throws IOException, ExecutionException, InterruptedException {
    System.out.println("scroll 模式启动!");
    Date  begin = new Date();
    SearchResponse scrollResponse = client.prepareSearch(Index).setTypes(TYPE)
            .setSearchType(SearchType.SCAN).setSize(5000).setScroll(TimeValue.timeValueMinutes(1))
            .execute().actionGet();
    long count = scrollResponse.getHits().getTotalHits();//第一次不返回数据
    for(int i=0,sum=0; sum<count; i++) {
        scrollResponse = client.prepareSearchScroll(scrollResponse.getScrollId())
                .setScroll(TimeValue.timeValueMinutes(8))
                .execute().actionGet();
        sum += scrollResponse.getHits().hits().length;
 
        SearchHits searchHits = scrollResponse.getHits();
        List<UpdateRequest> list = new ArrayList<UpdateRequest>();
        for (SearchHit hit : searchHits) {
            String id = hit.getId();
            Map<String, Object> source = hit.getSource();
            if (source.containsKey("TimeFormat")) {   //这个很重要,如果中间过程失败了,在执行时,起到过滤作用,提高效率。
                System.out.println("TimeFormat已经存在!");
            }else{
            Integer year = Integer.valueOf(source.get("Year").toString());
            Integer month = Integer.valueOf(source.get("Mon").toString());
            Integer day = Integer.valueOf(source.get("Day").toString());
            Integer hour = 0;
             if(source.containsKey(""Hour"")){   //处理Hour不存在的情况
                  hour = Integer.valueOf(source.get("Hour").toString());
             }else{
                  hour = 0;
             }
 
            String time = getyear_month_day_hour(year, month, day, hour); //这个方法自定义,用来生成新字段TimeFormat的值,按需修改即可。
            System.out.println(time);
            UpdateRequest uRequest = new UpdateRequest()
                    .index(Index)
                    .type(Type)
                    .id(id)
                    .doc(jsonBuilder().startObject().field("TimeFormat", time).endObject());
            list.add(uRequest); 
            //client.update(uRequest).get();  //注释上一行,就是单个提交,大数据量效率很低,用一个list来使用bulk,批量提高效率
        }
    }
        // 批量执行
        BulkRequestBuilder bulkRequest = client.prepareBulk();
        for (UpdateRequest uprequest : list) {
            bulkRequest.add(uprequest);
        }
 
        BulkResponse bulkResponse = bulkRequest.execute().actionGet();
 
        if (bulkResponse.hasFailures()) {
            System.out.println("批量错误!");
        }
 
        System.out.println("总量" + count + " 已经查到" + sum);
    }
    Date  end = new Date();
    System.out.println("耗时: "+(end.getTime()-begin.getTime()));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值