# TestElasticSearch
**Repository Path**: cyhgyq/test-elastic-search
## Basic Information
- **Project Name**: TestElasticSearch
- **Description**: 学习ElasticSearch
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-08-06
- **Last Updated**: 2022-09-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# ElasticSearch
6.x 和7.x版本很大区别,学习7.x
分原生api和RestFul高级
SQL:like 方式搜索大数据很慢,即使加了索引也达不到要求
ElasticSearch: 大数据量的搜索, 搜索框架还有Solr, ElasticSearch比Solr快50倍左右
要求:
jdk1.8, ElasticSearch客户端,界面工具
下载: https://www.elastic.co/cn/elasticsearch/ 很大1个多G
需要下载核心包(官网下载),analysis-ik分词器(github上下载),head-mast处理器(github上下载下面会说), kibana
可以在windows或linux下学习
ELK三剑客,elasticaSearch, Logstash,Kibana, 解压即用
解压出现文件夹就可以使用了:
bin:启动文件, 双击elasticsearch.bat启动
config: 配置文件
log4j2:日志配置文件
jvm.option: java虚拟机的配置
-Xms256m 需要的内存,默认1G, 很大服务器和电脑跑步起来,改成256m
-Xmx256m
elasticsearch.yml: elasticsearch的配置文件,默认9200端口, 小心跨域问题
lib: jar包
modules: 功能模块
plugin: 插件,如ik分词器插件
启动后浏览器输入:127.0.0.1:9200
安装可视化界面:百度搜索:elasticsearch head 得到地址: https://github.com/mobz/elasticsearch-head/ 下载这个前端项目运行起来, 默认端口9100
浏览器输入:127.0.0.1:9100, 在界面的链接输入框中输入:http://localhost:9200, 连接失败,f12打印中出现跨域问题
在elaticsearch.yml的配置文件配置一下:
http.cors.enabled: true
http.cors.allow-origin: "*"
来解决跨域问题,重新连接成功了
界面里面 索引 其实表示数据库的意思
数据浏览 可以看到某个索引的所有数据
复合查询 就是一些查询json语句
head就是一个数据展示工具,不建议在里面写查询语句,因为里面语句没有格式化,应该在kibana里面写查询语句
安装Kibana: https://www.elastic.co/cn/kibana
注意下载的版本必须和上面下载的elasticSearch的版本一致
解压需要一些时间,然后双击bin文件夹中的启动文件, 里面会显示http://localhost:5601, 浏览器打开
点击界面的小扳手图标,里面就可以写各种查询语句了
汉化:config/kibana.yml i18.local: "en" 改成 zh-CN, 重启项目
集群、节点、索引、类型、文档、分片、映射是什么?
elasticSearch是面向文档的,一切都是json
mysql与elasticsearch对比:
mysql elasticsearch
数据库 索引(indices)
表 types(已经弃用)
行 documents(文档)
字段 fields
一个人也是一个群,也会进行分片
安装ik分词器:https://github.com/medcl/elasticsearch-annlysis-ik 下载完成后,解压,在elaticsearch的plugins中建立文件夹名字ik, 将解压的内容拷贝到这个文件夹中,重启elasticsearch
在kibana的小扳手里面输入下面内容: ik_smart 智能分词, ik_max_word 最细粒度分词
GET _analyze
{
"analyzer": "ik_smart",
"text": "中国"
}
GET _analyze
{
"analyzer": "ik_max_word",
"text": "中国"
}
自定义词加到ik分词器中:
config下面加一个文件:my.dic, 里面输入我们的词
config/IKAnaly.cfg.yml ,配置: my.dic 重启elasticsearch, 里面可以配置新词和停止使用的词, 还有远程词典的配置,这样就不需要重启了,es会每隔一段时间从服务器拉取词典
Rest基本语法:
创建索引并插入一条数据:
PUT test1/_doc/1 /索引名/_doc/文档id _doc是类型,固定用这个, 一起自定义类型功能被弃用了
{
"name": "cyh",
"age": 18
}
创建索引,不插入数据,但是指定字段类型,java类对应方便,字段类型不能够修改 ,如果需要改,必修新建索引,将旧的索引复制到新的索引中,有很多类型,可以在网上找
PUT test2
{
"settings" : {
"analysis": {
"analyzer": {
"ik": {
"tokenizer": "ik_max_word" //添加ik分词器的设置 有ik_max_work和ik_smart两种, 这一句可以不加
}
}
}
}
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "ik_max_word" //表示加ik分词器, 这一句可以不加
},
"age": {
"type": "long"
}
}
}
}
获取各个字段的类型
GET /test2/_mapping
GET /test2/_mapping/logs
GET /test2/_mapping/logs/field/age
添加字段,shez leix
POST /test2/_mapping/logs
{
"properties": {"number": {"type": "text"}}
}
设置分片数,默认5个, 只能初始化是设置,后续不能修改
PUT /test2/_settings
{
"number_of_replicas": 2
}
获取分片数
GET /test2/_settings
索引拷贝,可以解决字段类型变更的问题,即类似数据库拷贝
POST _reindex
{
"source": {
"index": "test2"
},
"dest": {
"index": "test3"
}
}
测试分词
GET _analyze?pretty
{
"analyzer": "ik_max_word",
"text": "重卡是家乐福"
}
获取索引的信息:
GET test2
GET _cat/ 会获得很多默认的信息
GET test1/_doc/1
GET test1/_doc/_search?q=name:cyh 搜索这个库里面符合条件的, 分词器只对text类型有作用,对keyword类型没有作用, 查询结果中_score表示匹配度,max_score最大的匹配分值
GET test1/_doc/_search 如果后加上?pretty表示格式化,使变得更好看
{
"query": {
"match": { //match匹配查询会使用分词器或者term倒排查询直接查找精确的值, 还可以改成range
"name": "cyh" //可以用空格隔开多个词表示分别查询匹配多个值符合
}
"bool" : { //bool查询, 即多条件查询
"must": [ //must表示所有条件都要符合, should表示可以满足也可以不满足这个条件,must_not表示不符合下面条件
{
"match": {
"name": "cyh" 如果是["cyh", "cyh2"]则表示满足这两个的一个条件就行
}
},
{
"match": {
"age": 10
}
}
],
"filter": {
"range": {
"age": {
"gte": 10,
"lt": 18 //表示查出的结果过滤出年龄小于18岁的, gt gte lt lte
}
}
}
}
}
"_source": ["name", "age"], //过滤字段,表示只查出这几个字段
"sort": [ //查询结果的排序方式
{
"age": {
"order": "desc"
}
}
],
"from": 0, //分页,从第几个数据开始, 这种方式只适用于小量数据的情况
"size": 10, //分页,查询结果几个数据, 设置1,表示只查1个数据
"highlight": { //高亮显示name匹配的结果
"pre_tags": "
", //前缀
"post_tags": "
", //后缀
"fields": {
"name": {}
}
}
}
更新数据:
POST test1/_doc/1/_update //如果没有加_update, 则除了更新字段,其它字段都会删除
{
"doc": {
"name": "cyh2"
}
}
删除命令: DELETE test1/_doc/1
批量添加数据
PUT /tes2/_bulk {}
大量数据分页查询时
先得到scrollId
GET test2/_search?scroll=3m
{
"query": {"match_all": {}},
"size": 3
}
通过scrollId查询
GET /_search/scroll
{
"scroll": "1m", //数据缓存时间
"scroll_id": "上一步得到的scrollId"
}
# springboot集成elasticSearch
在官网找Elasticsearch Clients,点击进入,里面有不同平台的集成方式,推荐java Rest 点击进去---选择Java High Level Rest Client, 选择高级的客户端, 里面有全套的文档
idea->Spring initializr->NoSql->Elasticsearch
idea->Project Structure->Project->jdk1.8,版本改成8
idea->settings->java compier->改成jdk1.8, javaScript->es6
修改elasticSearch的pom版本,否则出错
7.6.1 //跟我们服务器安装的elasticsearch版本要一致
代码:
@Configuration
public class ElasticSearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient client = new RestHighLevelClient (
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http") //如果集群有多个,逗号隔开填多个
)
)
return client;
}
}
测试文件中使用:
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient client;
//创建索引
@Test
void testCreateIndex() {
//创建索引请求
CreateIndexRequest request = new CreateIndexRequest("cyh_index");
//执行请求, 获得响应数据
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
}
//获取索引
@Test
voie testExistIndex() {
GetIndexRequest request = new GetIndexRequest("cyh_index");
boolean exists = client.indices.exists(request, RequestOptions.DEFAULT);
}
//删除索引
@Test
void testDeleteIndex() {
DeleteIndexRequest request = new DeleteIndexRequest("cyh_index");
AcknowledgeResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
//delete.isAcknowledged();表示是否删除成功
}
//添加文档
@Test
void testAddDocument() {
User user = new User("cyh", 18);
IndexRequest request = new IndexRequest("cyh_index");
//设置elesticSearch的自带的东西
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
//设置elesticSearch的文档体
request.source(JSON.toJSONString(user).XContentType.JOSN);
//客户端发送请求
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
}
//获取文档,判断文档是否存在
@Test
void testIsExists() {
GetRequest getRequest = new GetRequest("cyh_index", "1");
boolean exists = clients.exists(getRequsts, RequestOptions.DEFAULT);
}
//获取文档的信息
@Test
void testGetDocument() {
GetRequest getRequest = new GetRequest("cyh_index", "1");
GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
//打印response 和 response.getSourceAsString()
}
//更新文档
@Test
void testUpdateDocument() {
UpdateRequest updateRequest = new UpdateRequest("cyh_index", "1");
updateRequest.timeout("1s");
User user = new User("cyh2", 18);
updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);
UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);
}
//删除文档
@Test
void testDeleteDocument() {
DeleteRequest request = new DeleteRequest("cyh_index", "3");
request.timeout("1s");
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
//通过deleteResponse.status()来判断是否删除成功
}
//大批量的插入数据, 批量删除更新也是类似的操作
@Test
void testBulkRequest() {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
ArrayList userList = new ArrayList();
userList.add(new User("cyh3", 20));
userList.add(new User("cyh4", 23));
for(int i = 0; i < userList.size(); i++) {
bulkRequest.add(
new IndexRequest("cyh_index")
.id("" +(i+1)) //这句不设置则是随机数
.source(JOSN.toJSONString(userList.get(i), XContentType.JSON));
);
}
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
//打印bulkResponse.hasFailures(), 返回false表示成功
}
//查询
//SearchRequest 搜索请求
//SearchSourceBuilder 条件构建
//HighLightBuilder 构建高亮
//TermQueryBuilder 构建精确查询
//MatchAllQueryBuilder 构建匹配查询
@Test
void testSearch() {
SearchRequest searchRequest = new SearchRequest("cyh_index");
//构建搜索条件
SearchSourceBuilder sourceBuilder new SearchSourceBuilder();
//查询条件,我们可以使用QueryBuilders工具来实现
//QueryBuilders.termQuery() 精确查询
//QueryBuilder.matchAllQuery() 匹配所有
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "cyh");
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDES));
//分页
sourceBuilder.from(0);
sourceBuilder.size(10);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//打印searchResponse.getHits()
}
//高亮的部分代码
@Test
void testHighLight() {
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title"); //需要高亮的字段
highlightBuilder.requireFieldMetch(false); //取消多个高亮显示
highlightBuilder.preTags(""); //前缀
highlightBuilder.postTags(""); //后缀
sourceBuilder.highlighter(highlightBuilder);
Map highlightFields = hit.getHighlightFields(); //高亮字段
HighlightField title = highlightFields.get("title");
Map sourceAsMap = hit.getSourceAsMap(); //非高亮字段
//将高亮字段替换掉原来非高亮字段
}
//java从网站上爬取数据进行清洗的依赖包
org.jsoup
jsoup
1.10.2
第二个视频的方式 API的方式
private TransportClient client = null;
@BeforeTest
public void getClient() {
Settings settings = Settings.builder().put("aa", "bb").build();
TransportAddress transportAddress1 = new TransportAddress(InetAddress.getByName("node01"), 9300);
client = new PreBuiltTransportClient(settings)
.addTransportAddress(transportAddress1)
.addTransportAddress(transportAddress2);
}
@AfterTest
public void closeClient() {
client.close();
}
@Test
public void createIndex1() {
IndexRequstBuilder indexRequestBuilder = client.prepareIndex("aa", "bb", "1").setSource(json, XContentType.JSON);
indexRequestBuilder.get();
}
@Test
public void createIndex2() {
IndexRequstBuilder indexRequestBuilder = client.prepareIndex("aa", "bb", "2").setSource(map, XContentType.JSON);
indexRequestBuilder.get();
}
@Test
public void createIndex3() {
IndexRequstBuilder indexRequestBuilder = client.prepareIndex("aa", "bb", "3").setSource(new XContentFactory().jsonBuilder().startObject().field("name", "cyh").field("age", "10").endObject());
indexRequestBuilder.get();
}
@Test
public void createIndex4() {
IndexRequstBuilder indexRequestBuilder = client.prepareIndex("aa", "bb", "4").setSource(JSONObject.toJSONString(user), XContentType.JSON);
indexRequestBuilder.get();
}
//批量添加
@Test
public void addBatch() {
BulkRequest bulkRequestBuilder = client.prepareBulk();
IndexRequstBuilder i1 = client.prepareIndex("aa", "bb", "5").setSource(json1, XContentFactory.JSON);
IndexRequstBuilder i2 = client.prepareIndex("aa", "bb", "6").setSource(json2, XContentFactory.JSON);
BulkRequestBuilder add = bulkRequestBuilder.add(i1).add(i2);
add.get();
}
//更新数据
@Test
public void updateIndex() {
client.prepareUpdate("aa", "bb", "2").setDoc(json, XContentFactory.JSON).get();
}
//删除
@Test
public void deleteIndex() {
client.prepareDelete("aa", "bb", "2").get();
}
//删除整个索引库
@Test
public void deleteAllDB() {
client.admin().indices().prepareDelete("aa").execute().actionGet();
}
//查询
@Test
public void getBySystemId() {
GetRequestBuilder builder = client.prepareGet("aa", "bb", "2");
GetResponse res = builder.get();
}
//查询所有数据
@Test
public void queryAll() {
SearchResponse res = client.prepareSearch("aaa").setTypes("bb").setQuery(QueryBuilders.matchAllQuery()).get();
res.getHits();
}
//范围查询
@Test
public void queryRange() {
SearchResponse res = client.prepareSearch("aaa").setTypes("bb").setQuery(QueryBuilders.rangeQuery("age").gt(18).lt(28)).get();
res.getHits();
}
//词条查询
@Test
public void queryTerm() {
SearchResponse res = client.prepareSearch("aaa").setTypes("bb").setQuery(QueryBuilders.termQuery("say", "熟悉")).get();
res.getHits();
}
//模糊查询,主要查询英文字母拼写错误的情况
@Test
public void queryFuzzy() {
SearchResponse res = client.prepareSearch("aaa").setTypes("bb").setQuery(QueryBuilders.fuzzyQuery("say", "helol").fuzziness(Fuzziness.TWO)).get();
res.getHits();
}
//通配符查询 用.和*
@Test
public void queryWildCard() {
SearchResponse res = client.prepareSearch("aaa").setTypes("bb").setQuery(QueryBuilders.wildcardQuery("say", "hel*")).get();
res.getHits();
}
//多条件查询: booleanQuery
@Test
public void queryWildCard() {
RangeQueryBuilder age = QueryBuilders.rangeQuery("age").get(18).lt(28);
TermQueryBuilder sex = QueryBuilders.termQuery("sex", "1");
SearchResponse res = client.prepareSearch("aaa").setTypes("bb").setQuery(QueryBuilders.boolQuery().should(age).must(sex)).get();
}
//分页查询
@Test
public void queryPage() {
SearchResponse res = client.prepareSearch("aaa").setTypes("bb").setQuery(QueryBuilders.matchAllQuery()).addSort("id", SortOrder.ASC).setFrom(2).setSize(5);
}
//高亮查询
@Test
public void queryHighLighter() {
HighlightBuilder h = new HighlightBuilder();
h.field("say").preTags("");
SearchResponse res = client.prepareSearch("aaa").setTypes("bb").setQuery(QueryBuilders.matchAllQuery()).highlighter(h).get();
}
//分组查询
@Test
public void queryGroup() {
TermsAggregationBuilder a = AggregationBuilders.terms("nn").field("mm");
SearchResponse res = client.prepareSearch("aaa").setTypes("bb").addAggregation(a).get();
}
//统计数量, 最值,平均值,分组求和,聚合排序
@Test
public void queryCount() {
}
# ELK日志:第二篇视频:
elasticSearch 全文检索框架
logstash 日志采集框架
kibana 日志界面显示框架
elasticSearch不能用root用户来启动,必须用普通用户来安装启动
使用root用户给机器创建普通用户:
useradd es
mkdir -p /export/servers/es
chown -R es:es /export/servers/es //root用户创建的东西,其他用户不能用,所以改成es用户es组可以使用
passwd es 回车, 设置密码
为普通用户es创建sudo权限
用root用户执行下面命令
visudo
找到root ALL=(ALL) ALL, 下面增加一行: es ALL=(ALL) ALL 表示es用户可以在任何地方使用任何命令
上传下载安装包解压
断电连接linux的工具, 重新连接,用es用户登录,执行下面命令
cd /home/es/
wget https://压缩包地址
tar -zxf elasticSearch.tar.gz -C /export/server/es/
修改配置文件:
修改elasticsearch.yml
cd /export/servers/es/elasticsearch-6.7.0/config
mkdir -p /export/servers/es/elasticsearch-6.7.0/logs
mkdir -p /export/servers/es/elasticsearch-6.7.0/datas
rm -rf elasticsearch.yml
vim elasticsearch.yml
cluster.name: myes
node.name: node01 //主机名
path.data: /export/servers/es/elasticsearch-6.7.0/datas
path.logs: /export/servers/es/elasticsearch-6.7.0/logs
network.host: 192.168.52.100 //当前服务器的地址
http.port 9200
discovery.zen.ping.unicast.hosts: ["node01", "node02", "node03"]
bootstrap.system_call_filter: flase
bootstrap.memory_lock:false
http.cors.enabled: true
http.cors.allow-origin: "*"
修改jvm.option 里面-Xms1g和Xmx1g,表示需要的内存,可以改成-Xms256m 和 -Xmx256m
使用命令scp -r elasticsearch-6.7.0/ node03:$PWD 将这个文件夹拷贝到其它服务器上去, 修改里面的node.name和network.host, 一共有node01,node02,node03的三台机器
解决报错的三个问题
解决问题一
sudo vi /etc/security/limits.conf
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
解决问题二
sudo vi /etc/security/limits.d/90-nproc.conf
将* soft nproc 1024改成 * soft nproc 4096
解决问题三 每次启动es都要执行下面的命令
sudo sysctl -w vm.max_map_count=262144
启动es服务器
nohup /export/servers/es/elasticsearch-6.7.0/bin/elasticsearch 2>&1 &
jps
浏览器访问:http://node01:9200/?pretty
安装elasticsearch-head插件
1.安装node.js
下载安装包
cd /home/es/
wget https://node的安装包地址
tar -zxvf node.tar.gz -C /export/servers/es/
创建软连接
sudo ln -s /export/servers/es/node-v8.1.0-linux-x64/lib/node_moduls/npm/bin/npm-cli.js /usr/local/bin/npm
sudo ln -s /export/servers/es/node-v8.1.0-linux-x64/bin/node /usr/local/bin/node
修改环境变量
sudo vim /etc/profile
export NODE_HOME=/export/servers/es/node-v8.1.0-linux-x64
export PATH=:$PATH:$NODE_HOME/bin
2.安装elasticsearch-head插件
将elasticsearch-head-compile-after.tar.gz 上传到node01机器的/home/es路径下面
解压安装包
cd /home/es/
tar -zxvf xxx.tar.gz -C /export/servers/es
修改Gruntfile.js
cd /export/servers/es/elasticsearch-head
vim Gruntfile.js
将hostname改成 hostname: '192.168.100.100' 自己机器的ip
修改app.js
cd /export/servers/es/elasticsearch-head/_site
vim app.js
将http://localhost:9200改成http://node01:9200
启动head服务
cd /export/servers/es/elaticsearch-head/node_modules/grunt/bin
进程前台启动
./grunt server
进程后台启动
nohub ./grunt server >/dev/null 2>&1 &
浏览器访问: http://node01:9100
安装kibana
下载安装包
cd /home/es/
wget https://安装包地址
tar -zxf xxx.tar.gz -C /export/servers/es/
修改配置文件
cd /export/servers/es/kibana/config/
vi kibana.yml
server.host: "node01"
elasticsearch.hosts: ["http://node01:9200"]
启动
cd /export/servers/es/kibana/
nohup bin/kibana >/dev/null 2>&1 &
浏览器访问: http://node01:5601 等一段时间多刷新几次才会出现
安装ik分词器
cd /home/es
wget https://分词器安装包的地址
mkdir /export/servers/es/elasticsearch-6.7.0/plugins/analysis-ik/
unzip 是一个zip的包,解压,将解压的内容复制到上面创建的文件夹中
重启elasticsearch
elasticSearch安装sql插件,就可以像使用sql语句一样来查询语句,https://github.com/NLPchina/elasticsearch-sql/
Logstash的安装, 在elasticSearch的官网中找到Logstash, 里面有三个重要的插件:Input plugins 用于采集来源, Output plugins采集的数据保存到哪里, Filter plugins 对采集的数据加工和转换
Logstash的安装:
cd /home/es/
wget https://logstash的地址
tar -zxf logstash.tar.gz -C /export/servers/es/
配置input和output插件, 查看官网
bin/logstash -e 'input {stdin{}} output{stdout{codec => rubydebug}}'
ELK的配置:
https://blog.csdn.net/janthinasnail/article/details/111064029
https://blog.csdn.net/chj_1224365967/article/details/119805341