开源的高扩展的分布式搜索引擎
环境安装
安装可视化界面 es head插件
- 下载地址 https://githab.com/mobz/elasticsearch-head/
- cnpm install 下载依赖(需要node.js环境)
- npm run start 启动服务
启动命令npm run startC:\MySpace\Environment\Elasticsearch\elasticsearch-head-master\elasticsearch-head-master>npm run start> elasticsearch-head@0.0.0 start> grunt serverRunning "connect:server" (connect) taskWaiting forever...Started connect web server on http://localhost:9100
- 解决跨域问题
..\elasticsearch-7.6.1\config\elasticsearch.yml 中新增配置配置内容:http.cors.enabled: truehttp.cors.allow-origin: "*"
重启服务 双击bin目录下的enasticsearch.bat重启
通过 9100端口访问
安装kibana
地址:https://www.elastic.co/cn/elasticsearch/
解压 启动(双击.bat)
默认端口:5601
概念
elasticsearch层级
索引
表(已弃用)
文档
- 字段
天然支持分布式:es中存在分片的概念
使用倒排索引
倒排索引
| 文档id | 内容 |
|---|---|
| 1 | 小明 |
| 2 | 小明 |
| 3 | 小明,小红 |
| 4 | 小红 |
倒排索引
| 内容 | 索引 |
|---|---|
| 小明 | 1,2,3 |
| 小红 | 3,4 |
通过文档中的内容生成倒排索引,提高查询效率。例如查询小红,通过索引得知在id为3和4中存在相关内容,那么就只会在这两个文档中查找。
IK分词器
ik提供了两种分词算法ik_smart和ik_max_word其中ik_smart为最少切分,ik_max_word为最细粒度划分。
下载安装
地址:https://github.com/medcl/elasticsearch-analysis-ik
解压到es的plugins目录下
重启es
[2022-01-16T17:25:24,441][INFO ][o.e.p.PluginsService ] [LAPTOP-NGE1V8E1] loaded plugin [analysis-ik]
查看加载的插件
C:\MySpace\Environment\Elasticsearch\elasticsearch-7.6.1\bin>elasticsearch-plugin listfuture versions of Elasticsearch will require Java 11; your Java version from [C:\MySpace\Environment\jdk\jre] does not meet this requirementelasticsearch-analysis-ik-7.6.1
分词测试
基本操作
数据类型
字符串类型
- text keyword
数值类型
- long, integer, short ,byte ,double ,float, half float, scaled float
日期类型
- date
布尔类型
- boolean
二进制类型
- binary
语法
| 方法 | restful请求路径 | 描述 |
|---|---|---|
| PUT | localhost:9200/索引名/类型名/文档id | 创建文档(指定id) |
| POST | localhost:9200/索引名/类型名 | 创建文档(随机id) |
| POST | localhost:9200/索引名/类型名/文档id/_update | 修改文档 |
| DELETE | localhost:9200/索引名/类型名/文档id | 删除文档 |
| GET | localhost:9200/索引名/类型名/文档id | 通过文档id查询 |
| POST | localhost:9200/索引名/类型名/文档id/_search | 查询所有数据 |
新增
创建索引规则
PUT /索引名{"mappings": {"properties": {"字段名":{"type": "字段类型"},"字段名":{"type": "字段类型"}}}}例:PUT /test2{"mappings": {"properties": {"name":{"type": "text"},"age":{"type": "integer"}}}}
获取所以规则
GET test2
新增数据
# PUT /索引名称/类型名/id{请求体}例:PUT /test1/_doc/1{"name":"铁柱","sex":"男"}
修改
PUT /索引名/类型名/id #修改会覆盖所有的字段{请求体}例:PUT /test1/_doc/3{"name":"铁柱","sex":"男"}POST /索引名/_update/id #只会修改指定字段的值{请求体}例:POST /test1/_update/1{"doc":{"name":"狗蛋",}}
删除
DELETE /索引名/类型名/id #删除数据DELETE 索引名 #删除索引例:DELETE /test1/_doc/2DELETE test
查询
GET test1/_doc/1 #通过文档id查询
复合查询
语法
match只能单条件查询
_source 展示字段
sort 排序
from size 分页
hightlight 高亮展示
GET 索引/表/_search{"query":{"match":{"字段":"值"}},"_source":["展示字段"],"sort":[{"排序字段":{"order":"排序方式" #desc asc}}],"from": 开始位置的下标, #从0开始"size":返回数据量}
例:
GET person/_doc/_search{"query":{"match":{"name":"铁柱"}},"_source":["age"],"sort":[{"age":{"order":"desc"}}],"from":0,"size":1}
match与term
match可以通过分词进行模糊查询
term 只会进行精确匹配 但是会使用倒排索引 效率更高
布尔值查询(可以实现多条件查询)
must 且操作 查询满足所有条件的数据
should 或操作 查询满足其中一项条件的数据
must_not 非操作 查询不满足条件的数据
GET 索引/表/_search{"query":{"bool":{"must":[{"match":{"字段":"值"}},{"match":{"字段":"值"}}]}}}例:GET person/_doc/_search{"query":{"bool":{"must":[{"match":{"name":"铁柱"}},{"match":{"age":1}}]}}}
过滤器
filter 进行数据过滤
gt 大于 lt小于 gte大于等于 lte 小于等于
GET person/_doc/_search{"query":{"bool":{"must":[{"match":{"name":"翠花"}}],"filter":{"range":{"age":{"gt":10,"lt":50}}}}}}
扩展命令
GET _cat/health #查看健康值GET _cat/indices?v #
集成SpringBoot
springboot文档地址 https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.rest
导入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>
配置
@Configurationpublic class ElacticSearchConfig extends AbstractElasticsearchConfiguration {@Override@Beanpublic RestHighLevelClient elasticsearchClient() {final ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200").build();return RestClients.create(clientConfiguration).rest();}}
索引操作
@Qualifier(value = "elasticsearchClient")@Autowiredprivate RestHighLevelClient client;/*** 创建索引* @throws IOException*/@Testpublic void createIndex() throws IOException {//创建索引请求CreateIndexRequest index = new CreateIndexRequest("test_index");//客户端执行请求 获取响应CreateIndexResponse createIndexResponse = client.indices().create(index, RequestOptions.DEFAULT);}/*** 判断索引是否存在* @throws IOException*/@Testvoid indexExist() throws IOException {GetIndexRequest request = new GetIndexRequest("test_index");boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);}/*** 删除索引* @throws IOException*/@Testvoid indexDelete() throws IOException {DeleteIndexRequest request = new DeleteIndexRequest("test_index");AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);}
文档操作
@Qualifier(value = "elasticsearchClient")@Autowiredprivate RestHighLevelClient client;/*** 插入文档* @throws IOException*/@Testvoid createDoc() throws IOException {User user = new User("小明",15);IndexRequest request = new IndexRequest("test_index");//拼装请求//添加idrequest.id("111");//添加内容request.source(JSON.toJSONString(user), XContentType.JSON);//设置过期时间request.timeout(TimeValue.timeValueSeconds(1));//执行请求IndexResponse response = client.index(request, RequestOptions.DEFAULT);System.out.println(request.toString());}/*** 判断文档是否存在* @throws IOException*/@Testvoid existDoc() throws IOException {GetRequest request = new GetRequest("test_index");request.id("111");//不获取返回的_source上下文request.fetchSourceContext(new FetchSourceContext(false));//判断文档是否存在boolean exists = client.exists(request, RequestOptions.DEFAULT);System.out.println(exists);}/*** 获取文档信息*/@Testvoid getDoc() throws IOException {GetRequest request = new GetRequest("test_index");request.id("111");GetResponse response = client.get(request, RequestOptions.DEFAULT);System.out.println(response.getSource());}/*** 更新文档*/@Testvoid updateDoc() throws IOException {UpdateRequest request = new UpdateRequest("test_index","111");request.timeout(TimeValue.timeValueSeconds(1L));User user = new User("小明", 25);request.doc(JSON.toJSONString(user),XContentType.JSON);UpdateResponse response = client.update(request, RequestOptions.DEFAULT);System.out.println(response.status());}/*** 删除文档记录*/@Testvoid deleteDoc() throws IOException {DeleteRequest request = new DeleteRequest("test_index", "111");request.timeout(TimeValue.timeValueSeconds(1L));DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);System.out.println(response.status());}
批量操作
/*** 批量插入数据*/@Testvoid insertManyDoc() throws IOException {BulkRequest request = new BulkRequest();request.timeout(TimeValue.timeValueSeconds(10L));ArrayList<User> users = new ArrayList<>();users.add(new User("用户1",1));users.add(new User("用户2",2));users.add(new User("用户3",3));for (int i = 0; i < users.size(); i++) {//插入时使用IndexRequest 批量删除替换为DeleteRequest 批量更新使用UpdateRequest即可request.add(new IndexRequest("test_index").id(String.valueOf(i)).source(JSON.toJSONString(users.get(i+1)),XContentType.JSON));}BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);System.out.println(bulk.status());}
查询
/*** 查询*/@Testvoid testSearch() throws IOException {SearchRequest request = new SearchRequest(indexName);//构架搜索条件SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//查询条件//QueryBuilders.termQuery 精确匹配//QueryBuilders.matchAllQuery 匹配所有TermQueryBuilder queryBuilder = QueryBuilders.termQuery("age", 2);searchSourceBuilder.query(queryBuilder);searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));request.source(searchSourceBuilder);SearchResponse search = client.search(request, RequestOptions.DEFAULT);//打印结果for (SearchHit hit : search.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}
