1.2 ElasticSearch特性ElasticSearch vs Lucene的关系,简单⼀句话就是,成品与半成品的关系。
(1)Lucene专注于搜索底层的建设,而ElasticSearch专注于企业应用。
(2)Luncene是单节点的API,ElasticSearch是分布式的—为集群而⽣。
(3)Luncene需要⼆次开发,才能使用。不能像百度或谷歌⼀样,它只是提供⼀个接⼝需要被实现才能使用, ElasticSearch直接拿来用。
二、ElasticSearch逻辑结构安装管理便便
大规模分布式
多租户支持
高可用性
*** 作持久化
友好的RESTful API
集群–>index(索引)–>types(类型)–>document(文档)–>field(字段)
//index3 索引名,_doc 类型(默认为_doc),102 文档id名, "book_id" 字段名 POST index3/_doc/102 { "book_id":102, "book_name":"C++程序设计", "book_author":"谭浩强", "book_price":22.22, "book_desc":"C++程序设计中的名著" }
索引(index)
索引是ElasticSearch存放数据的地方,可以理解为关系型数据库中的⼀个数据库
索引的名字必须是全部⼩写,不能以下划线开头,不能包含逗号类型(type)
类型用于区分同⼀个索引下不同的数据类型,相当于关系型数据库中的表。
es 6.0 开始不推荐⼀个index下多个type的模式,并且会在 7.0 中完全移除。在7.0 的index下是⽆法创建多个 type文档(documents)
文档是ElasticSearch中存储的实体,类比关系型数据库,每个⽂档相当于数据库表中的⼀行数据。
索引的名字必须是全部⼩写,不能以下划线开头,不能包含逗号字段(fields)
⽂档由字段组成,相当于关系数据库中列的属性,不同的是ES的不同文档可以具有不同的字段集合。节点与集群
⼀个集群是由⼀个或多个节点组成的集合,集群上的节点都具备存储数据,并提供跨节点的索引和搜索功能。
集群通过⼀个唯⼀的名称作为标识,节点通过设置集群名称就可以加⼊相应的集群,当然这需要节点所在的网络能够发现集群。所以要注意在同⼀个网络中,不同环境、服务的集群的名称不能重复。
三、ElasticSearch安装(Linux)
3.1 Elastic 和 Elasticsearch
Elastic官⽹:https://www.elastic.co/cn/
Elasticsearch官⽹:https://www.elastic.co/cn/products/elasticsearch
Elastic有⼀条完整的产品线及解决方案:Elasticsearch、Logstash、Kibana等,这三个就是大家常说的ELK技术栈。
出于安全考虑,elasticsearch默认不允许以root账号运⾏
创建用户设置密码
[root@localhost ~]# useradd es [root@localhost ~]# passwd es Changing password for user es. New password: Retype new password: [root@localhost ~]# chmod 777 /usr/local 【授予es⽤户/usr/local⽬录 可读可写可执⾏权限】 [root@localhost ~]# su - es [es@localhost ~]$
检查JDK版本(需要JDK1.8+)
[es@localhost ~]# java -version openjdk version "1.8.0_222-ea" OpenJDK Runtime Environment (build 1.8.0_222-ea-b03) OpenJDK 64-Bit Server VM (build 25.222-b03, mixed mode)
将ES的压缩包上传⾄ /usr/local 目录并解压
[es@localhost local]$ tar -zxvf elasticsearch-7.6.1-linux-x86_64.tar.gz
进入elasticsearch-7.6.1中添加data 文件
[es@localhost local]# cd elasticsearch-7.6.1 [es@theo elasticsearch-7.6.1]#mkdir data [es@theo elasticsearch-7.6.1]# ls bin config data jdk lib LICENSE.txt log smodules NOTICE.txt plugins README.asciidoc
查看配置文件
[es@theo elasticsearch-7.6.1]# cd config [es@localhost config]# ls elasticsearch.yml jvm.options data log4j2.properties role_mapping.yml roles.yml users users_roles
修改 jvm.options(修改ElasticSearch占用的内存)
Elasticsearch基于Lucene的,而Lucene底层是java实现,因此我们需要配置jvm参数
[es@localhost config]# vim jvm.options # 默认配置如下 # Xms represents the initial size of total heap space # Xmx represents the maximum size of total heap space -Xms1g -Xmx1g #修改成 -Xms256m -Xmx256m
修改 elasticsearch.yml下面是做的单机安装的修改,如果要做集群,只需要在这个配置⽂件中添加其它节点信息即可。
# (修改集群节点信息)(当前是单节点配置) # ---------------------------------- Cluster -----------------------------------17 cluster.name: my-application # ------------------------------------ Node ------------------------------------23 node.name: node-1 # --------------------------------- Discovery ----------------------------------72 cluster.initial_master_nodes: ["node-1"] # (修改数据⽂件和⽇志⽂件存储⽬录路径) # ---------------------------- Paths ------------------------------ path.data: /usr/local/elasticsearch-7.6.1/data path.logs: /usr/local/elasticsearch-7.6.1/logs # (修改绑定的ip,默认只允许本机访问,修改为0.0.0.0后则可以远程访问) # ---------------------------- Network ------------------------------ # 默认只允许本机访问,修改为0.0.0.0后则可以远程访问 network.host: 0.0.0.0
进入elasticsearch/bin目录运行
[es@localhost elasticsearch-7.6.1]# cd /usr/local/elasticsearch-7.6.1/bin [es@localhost elasticsearch-7.6.1]# ./elasticsearch3.3 启动错误问题总结
错误1:内核过低
我们使用的是centos6,其linux内核版本为2.6。而Elasticsearch的插件要求至少3.5以上版本。不过没关系,我们禁用这个插件即可。
修改elasticsearch.yml文件,在最下面添加如下配置
bootstrap.system_call_filter: false
然后重启
错误2:⽂件权限不足
我们用的是es用户,⽽不是root,所以文件权限不⾜。
⾸先⽤root⽤户登录,然后修改配置⽂件
vim /etc/security/limits.conf
添加下面的内容:
* soft nofile 65536 * hard nofile 131072 * soft nproc 4096 * hard nproc 4096
错误3:线程数不够
[1]: max number of threads [1024] for user [es] is too low, increase to at least[4096]
这是线程数不够
继续修改配置
vim /etc/security/limits.d/20-nproc.conf
修改下⾯的内容:
soft nproc 1024 # 改为 soft nproc 4096
错误4:进程虚拟内存(要在root用户下 *** 作)
[3]: max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least[262144]
vm.max_map_count:限制⼀个进程可以拥有的VMA(虚拟内存区域)的数量
继续修改配置⽂件, vim /etc/sysctl.conf 添加下⾯内容:
vm.max_map_count=655360
修改完成之后在终端执行重启
##然后执⾏命令 sysctl -p
错误5:未设置节点
the default discovery settings are unsuitable for production use; at least one of [discovery.seed_ho...]
修改elasticsearch.yml
cluster.name: my-application node.name: node-1 cluster.initial_master_nodes: ["node-1"]四、安装Kibana
Kibana是⼀个基于Node.js的Elasticsearch索引库数据统计工具,可以利用Elasticsearch的聚合功能,生成各种图表,如柱形图,线状图,饼图等。
而且还提供了 *** 作Elasticsearch索引数据的控制台,并且提供了⼀定的API提示,⾮常有利于我们学习Elasticsearch的语法。
安装
kibana版本与elasticsearch保持⼀致,也是7.6.1解压到特定目录即可
tar -zxvf kibana-7.6.1-linux-x86_64.tar.gz
配置
进⼊安装目录下的config⽬录,修改kibana.yml文件:
server.port: 5601 server.host: "0.0.0.0
运行
进⼊安装目录下的bin目录启动
./kibana
发现kibana的监听端⼝是5601
我们访问:http://47.96.11.185:5601
在本地将下载的IK分词器压缩包解压到当前文件夹
将解压后的文件夹上传到云主机plugins文件夹中
重启es
[es@theo bin]$ ./elasticsearch5.2 测试
按ik_smart方式将“千锋武汉”分词,结果为“千” “峰” “武汉”
5.2 配置自定义词库(3种方式)
在elasticsearch-analysis-ik-7.6.1/plugins/ik/config⽬录中定义词典⽂件(.dic)在词典⽂件中定义⾃定义词汇elasticsearch-analysis-ik-7.6.1/plugins/ik/config/IKAnalyzer.cfg.xml加载⾃定义词典⽂件
六、ES基本 *** 作IK Analyzer 扩展配置 mywords.dic
6.1 数据类型ES是基于RESTful实现访问
不同 *** 作需要使用不同的请求方式
基于REST的基本访问规范
es中⼀个document表示⼀条记录,记录中field值的存储是有类型的
string
text 可分词
keyword 不能分词
Numeric datatypes
long , integer , short , byte , double , float , half_float , scaled_float
Date datatype
data — 日期的存储时以 long 类型存储的毫秒数
Boolean datatype
boolean — true | false | “true” | “false”
Binary datatype
binary 基于base64编码的字符串
Range datatypes
integer_range , float_range , long_range , double_range , date_range
//创建Index索引并指定field类型 PUT index4 { "mappings": { //设置存储在哪个分⽚上(可以不设置该字段,默认1) "settings": { "number_of_shards": 2 } //设置索引属性 "properties": { "bookId":{ "type": "long" }, "bookName":{ "type": "text" }, "author":{ "type": "keyword" }, "time":{ "type": "date" } } } }6.3 添加
POST index4/_doc/1 { "bookId":10001, "bookName":"Java程序设计", "author":"张三", "time":234567890 }6.4 修改
//使⽤新增 *** 作post的请求覆盖原记录 POST index1/_doc/103 { "book_id":103, "book_name":"Python王者归来", "book_author":"杰哥", "book_price":33.22, "book_desc":"Python从⼊⻔到放弃" } //使⽤_update修改 POST index1/_doc/103/_update { "book_id":103, "book_name":"Python王者归来", "book_author":"杰哥", "book_price":33.22, "book_desc":"Python从⼊⻔到放弃" }6.5 删除
DELETE index1/_doc/1036.6 查询
# 查询索引信息 GET index4 # 查询索引的mappings信息 GET index4/_mappings # 查询索引的属性设置 GET index4/_settings
term和terms
用于对keyword字段进行精确匹配,搜索之前不会对关键字进行分词
//查询field类型keyword的author字段是“张三”的 GET /index3/_search { "query": { "term": { "author": "张三" } } } //查询field类型keyword的author字段是“张三”或者“李四”的 GET /index3/_search { "query": { "terms": { "author": ["张三","李四"] } } }
match查询(重点)
match查询表示对text字段进行部分匹配(模糊查询),搜索之前会对关键词进行分词
GET /index4/_search { "query": { "match": { "bookName": "Java程序" } } } //match_all 表示查询全部内容,不指定任何条件 GET /index4/_search { "query": { "match_all": {} } } //multi_match 在多个字段中匹配同同时还有关键字的 GET /index4/_search { "query": { "multi_match": { "query": "Java", "fields": ["bookName","author"] } } }
高亮显示(重点)
对匹配的关键词进行特殊样式的标记
GET /index3/_search { "query": { "match": { "bookName": "Java" } }, //对查询出来的bookName字段的值进行红色字体显示 "highlight": { "fields": { "bookName": {} }, "pre_tags": "" } }
根据id查询
//根据⼀个id查询⼀个document GET /index4/_doc/1 //根据多个id查询多个document ==> select * from ... where id in [1,2,3] GET /index4/_search { "query":{ "ids":{ "values":["1","2","3"] } } }
其他查询
//prefix查询,根据指定字段的前缀值进⾏查询 GET /index4/_search { "query": { "prefix": { "author": { "value": "张" } } } } //fuzzy查询,模糊查询,输⼊⼤概的内容es检索相关的数据 GET /index4/_search { "query": { "fuzzy": { "bookName": { "value": "jav" } } } } //wildcard查询:正则匹配 GET /index4/_search { "query": { "wildcard": { "author": { "value": "张*" } } } } //range查询,根据范围进⾏查询 GET /index4/_search { "query": { "range" : { "bookId" : { "gt" : 10001, "lte" : 10003 } } } } //分⻚查询(查询从第一天数据开始每页20条 显示"bookId","bookName"字段信息) GET /index4/_search { "query": { "match_all": {} }, "_source": ["bookId","bookName"], "from": 0, "size": 20 }
复合查询—bool
复合查询——多条件查询
should ==> or 满足其一must ==> and 同时满足must_not ==> not 不是
GET /index4/_search { "query": { "bool":{ "must_not": [ { "match": { "bookName": "Java" } }, { "match": { "author": "张三" } } ] } } }
结果过滤—filter
filter——根据条件进⾏查询,不计算分数,会对经常被过滤的数据进⾏缓存
GET /index3/_search { "query": { "bool":{ "filter": [ { "match": { "bookName": "Java" } }, { "match": { "author": "张三" } } ] } } }七、SpringBoot整合ES
7.1 添加es的依赖官⽅参考地址 https://www.elastic.co/guide/en/elasticsearch/client/index.html
7.2 添加配置org.springframework.boot spring-boot-starter-data-elasticsearch
spring: elasticsearch: rest: uris: http://47.96.11.185:9200
如果是SSM项目则添加配置类
@Bean public RestHighLevelClient getRestHighLevelClient(){ //添加es所在Linux的公网ip和端口号及协议 HttpHost httpHost = new HttpHost("47.96.11.185", 9200, "http"); RestClientBuilder restClientBuilder = RestClient.builder(httpHost); RestHighLevelClient restHighLevelClient = new RestHighLevelClient(restClientBuilder); return restHighLevelClient; }7.3 使用 *** 作
@SpringBootTest class Esdemo3ApplicationTests { //注入restHighLevelClient对象 @Resource private RestHighLevelClient restHighLevelClient; @Test public void testCreateIndex() throws IOException { CreateIndexRequest createIndexRequest = new CreateIndexRequest("index4"); CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT); //b 为判断是否添加成功 boolean b = createIndexResponse.isAcknowledged); } @Test public void testDeleteIndex() throws IOException { DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("index4"); AcknowledgedResponse deleteIndexRes = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT); //b 为判断是否删除成功 boolean b = deleteIndexRes.isAcknowledged); } @Test public void testCreatedocument() throws IOException { Book book = new Book(10005,"平凡的世界","路遥",new Date().getTime()); //将book对象转换为json字符串格式存入es ObjectMapper objectMapper = new ObjectMapper(); String jsonStr = objectMapper.writevalueAsString(book); IndexRequest request = new IndexRequest("index3"); //设置文档id request.id("10005"); request.source(jsonStr, XContentType.JSON); IndexResponse indexResponse = restHighLevelClient.index(request,RequestOptions.DEFAULT); System.out.println(indexResponse); } @Test public void testSearch() throws IOException { SearchRequest searchRequest = new SearchRequest("index3"); //设置搜索条件内容searchSourceBuilder SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //查询显示分页条件 searchSourceBuilder.from(0); searchSourceBuilder.size(10); //查询全部字段 // searchSourceBuilder.query(QueryBuilders.matchAllQuery()); //查询部分字段 searchSourceBuilder.query(QueryBuilders.matchQuery("bookName","Java")); //设置高亮字段条件highlightBuilder HighlightBuilder highlightBuilder = new HighlightBuilder(); HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("bookName"); highlightBuilder.preTags(""); searchSourceBuilder.highlighter(highlightBuilder); searchRequest.source(searchSourceBuilder); SearchResponse searchResp = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT); //查询到结果hits 可使用迭代器遍历 SearchHits hits = searchResp.getHits(); //查询数据封装 Iteratoriterator = hits.iterator(); List products = new ArrayList<>(); while(iterator.hasNext()){ SearchHit searchHit = iterator.next(); String str = searchHit.getSourceAsString(); //将json字符串转换为对象 Product product = objectMapper.readValue(str, Product.class); //获取高亮字段(是一个数组) HighlightField highlightField = searchHit.getHighlightFields().get("productName"); if(highlightField != null){ String s = Arrays.toString(highlightField.fragments()); //将高亮字替换原属性 product.setProductName(s); } products.add(product); } } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)