
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();
//查询数据封装
Iterator iterator = 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条)