开源的高扩展的分布式搜索引擎

环境安装

安装可视化界面 es head插件

  1. 启动命令
  2. npm run start
  3. C:\MySpace\Environment\Elasticsearch\elasticsearch-head-master\elasticsearch-head-master>npm run start
  4. > elasticsearch-head@0.0.0 start
  5. > grunt server
  6. Running "connect:server" (connect) task
  7. Waiting forever...
  8. Started connect web server on http://localhost:9100
  • 解决跨域问题
    1. ..\elasticsearch-7.6.1\config\elasticsearch.yml 中新增配置
    2. 配置内容:
    3. http.cors.enabled: true
    4. http.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

  1. [2022-01-16T17:25:24,441][INFO ][o.e.p.PluginsService ] [LAPTOP-NGE1V8E1] loaded plugin [analysis-ik]

查看加载的插件

  1. C:\MySpace\Environment\Elasticsearch\elasticsearch-7.6.1\bin>elasticsearch-plugin list
  2. future versions of Elasticsearch will require Java 11; your Java version from [C:\MySpace\Environment\jdk\jre] does not meet this requirement
  3. elasticsearch-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 查询所有数据

新增

创建索引规则

  1. PUT /索引名
  2. {
  3. "mappings": {
  4. "properties": {
  5. "字段名":{
  6. "type": "字段类型"
  7. },
  8. "字段名":{
  9. "type": "字段类型"
  10. }
  11. }
  12. }
  13. }
  14. 例:
  15. PUT /test2
  16. {
  17. "mappings": {
  18. "properties": {
  19. "name":{
  20. "type": "text"
  21. },
  22. "age":{
  23. "type": "integer"
  24. }
  25. }
  26. }
  27. }

获取所以规则

  1. GET test2

新增数据

  1. # PUT /索引名称/类型名/id
  2. {请求体}
  3. 例:
  4. PUT /test1/_doc/1
  5. {
  6. "name":"铁柱",
  7. "sex":"男"
  8. }

修改

  1. PUT /索引名/类型名/id #修改会覆盖所有的字段
  2. {请求体}
  3. 例:
  4. PUT /test1/_doc/3
  5. {
  6. "name":"铁柱",
  7. "sex":"男"
  8. }
  9. POST /索引名/_update/id #只会修改指定字段的值
  10. {请求体}
  11. 例:
  12. POST /test1/_update/1
  13. {
  14. "doc":{
  15. "name":"狗蛋",
  16. }
  17. }

删除

  1. DELETE /索引名/类型名/id #删除数据
  2. DELETE 索引名 #删除索引
  3. 例:
  4. DELETE /test1/_doc/2
  5. DELETE test

查询

  1. GET test1/_doc/1 #通过文档id查询

复合查询

语法

match只能单条件查询

_source 展示字段

sort 排序

from size 分页

hightlight 高亮展示

  1. GET 索引/表/_search
  2. {
  3. "query":{
  4. "match":{
  5. "字段":"值"
  6. }
  7. },
  8. "_source":["展示字段"],
  9. "sort":[
  10. {
  11. "排序字段":{
  12. "order":"排序方式" #desc asc
  13. }
  14. }
  15. ],
  16. "from": 开始位置的下标, #从0开始
  17. "size":返回数据量
  18. }

例:

  1. GET person/_doc/_search
  2. {
  3. "query":{
  4. "match":{
  5. "name":"铁柱"
  6. }
  7. },
  8. "_source":["age"],
  9. "sort":[
  10. {
  11. "age":{
  12. "order":"desc"
  13. }
  14. }
  15. ],
  16. "from":0,
  17. "size":1
  18. }

match与term

match可以通过分词进行模糊查询

term 只会进行精确匹配 但是会使用倒排索引 效率更高

布尔值查询(可以实现多条件查询)

must 且操作 查询满足所有条件的数据

should 或操作 查询满足其中一项条件的数据

must_not 非操作 查询不满足条件的数据

  1. GET 索引/表/_search
  2. {
  3. "query":{
  4. "bool":{
  5. "must":[
  6. {
  7. "match":{
  8. "字段":"值"
  9. }
  10. },
  11. {
  12. "match":{
  13. "字段":"值"
  14. }
  15. }
  16. ]
  17. }
  18. }
  19. }
  20. 例:
  21. GET person/_doc/_search
  22. {
  23. "query":{
  24. "bool":{
  25. "must":[
  26. {
  27. "match":{
  28. "name":"铁柱"
  29. }
  30. },
  31. {
  32. "match":{
  33. "age":1
  34. }
  35. }
  36. ]
  37. }
  38. }
  39. }

过滤器

filter 进行数据过滤

gt 大于 lt小于 gte大于等于 lte 小于等于

  1. GET person/_doc/_search
  2. {
  3. "query":{
  4. "bool":{
  5. "must":[
  6. {
  7. "match":{
  8. "name":"翠花"
  9. }
  10. }
  11. ],
  12. "filter":{
  13. "range":{
  14. "age":{
  15. "gt":10,
  16. "lt":50
  17. }
  18. }
  19. }
  20. }
  21. }
  22. }

扩展命令

  1. GET _cat/health #查看健康值
  2. GET _cat/indices?v #

集成SpringBoot

springboot文档地址 https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.rest

导入依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4. </dependency>

配置

  1. @Configuration
  2. public class ElacticSearchConfig extends AbstractElasticsearchConfiguration {
  3. @Override
  4. @Bean
  5. public RestHighLevelClient elasticsearchClient() {
  6. final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
  7. .connectedTo("localhost:9200")
  8. .build();
  9. return RestClients.create(clientConfiguration).rest();
  10. }
  11. }

索引操作

  1. @Qualifier(value = "elasticsearchClient")
  2. @Autowired
  3. private RestHighLevelClient client;
  4. /**
  5. * 创建索引
  6. * @throws IOException
  7. */
  8. @Test
  9. public void createIndex() throws IOException {
  10. //创建索引请求
  11. CreateIndexRequest index = new CreateIndexRequest("test_index");
  12. //客户端执行请求 获取响应
  13. CreateIndexResponse createIndexResponse = client.indices().create(index, RequestOptions.DEFAULT);
  14. }
  15. /**
  16. * 判断索引是否存在
  17. * @throws IOException
  18. */
  19. @Test
  20. void indexExist() throws IOException {
  21. GetIndexRequest request = new GetIndexRequest("test_index");
  22. boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
  23. }
  24. /**
  25. * 删除索引
  26. * @throws IOException
  27. */
  28. @Test
  29. void indexDelete() throws IOException {
  30. DeleteIndexRequest request = new DeleteIndexRequest("test_index");
  31. AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
  32. }

文档操作

  1. @Qualifier(value = "elasticsearchClient")
  2. @Autowired
  3. private RestHighLevelClient client;
  4. /**
  5. * 插入文档
  6. * @throws IOException
  7. */
  8. @Test
  9. void createDoc() throws IOException {
  10. User user = new User("小明",15);
  11. IndexRequest request = new IndexRequest("test_index");
  12. //拼装请求
  13. //添加id
  14. request.id("111");
  15. //添加内容
  16. request.source(JSON.toJSONString(user), XContentType.JSON);
  17. //设置过期时间
  18. request.timeout(TimeValue.timeValueSeconds(1));
  19. //执行请求
  20. IndexResponse response = client.index(request, RequestOptions.DEFAULT);
  21. System.out.println(request.toString());
  22. }
  23. /**
  24. * 判断文档是否存在
  25. * @throws IOException
  26. */
  27. @Test
  28. void existDoc() throws IOException {
  29. GetRequest request = new GetRequest("test_index");
  30. request.id("111");
  31. //不获取返回的_source上下文
  32. request.fetchSourceContext(new FetchSourceContext(false));
  33. //判断文档是否存在
  34. boolean exists = client.exists(request, RequestOptions.DEFAULT);
  35. System.out.println(exists);
  36. }
  37. /**
  38. * 获取文档信息
  39. */
  40. @Test
  41. void getDoc() throws IOException {
  42. GetRequest request = new GetRequest("test_index");
  43. request.id("111");
  44. GetResponse response = client.get(request, RequestOptions.DEFAULT);
  45. System.out.println(response.getSource());
  46. }
  47. /**
  48. * 更新文档
  49. */
  50. @Test
  51. void updateDoc() throws IOException {
  52. UpdateRequest request = new UpdateRequest("test_index","111");
  53. request.timeout(TimeValue.timeValueSeconds(1L));
  54. User user = new User("小明", 25);
  55. request.doc(JSON.toJSONString(user),XContentType.JSON);
  56. UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
  57. System.out.println(response.status());
  58. }
  59. /**
  60. * 删除文档记录
  61. */
  62. @Test
  63. void deleteDoc() throws IOException {
  64. DeleteRequest request = new DeleteRequest("test_index", "111");
  65. request.timeout(TimeValue.timeValueSeconds(1L));
  66. DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
  67. System.out.println(response.status());
  68. }

批量操作

  1. /**
  2. * 批量插入数据
  3. */
  4. @Test
  5. void insertManyDoc() throws IOException {
  6. BulkRequest request = new BulkRequest();
  7. request.timeout(TimeValue.timeValueSeconds(10L));
  8. ArrayList<User> users = new ArrayList<>();
  9. users.add(new User("用户1",1));
  10. users.add(new User("用户2",2));
  11. users.add(new User("用户3",3));
  12. for (int i = 0; i < users.size(); i++) {
  13. //插入时使用IndexRequest 批量删除替换为DeleteRequest 批量更新使用UpdateRequest即可
  14. request.add(new IndexRequest("test_index").id(String.valueOf(i)).source(JSON.toJSONString(users.get(i+1)),XContentType.JSON));
  15. }
  16. BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
  17. System.out.println(bulk.status());
  18. }

查询

  1. /**
  2. * 查询
  3. */
  4. @Test
  5. void testSearch() throws IOException {
  6. SearchRequest request = new SearchRequest(indexName);
  7. //构架搜索条件
  8. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  9. //查询条件
  10. //QueryBuilders.termQuery 精确匹配
  11. //QueryBuilders.matchAllQuery 匹配所有
  12. TermQueryBuilder queryBuilder = QueryBuilders.termQuery("age", 2);
  13. searchSourceBuilder.query(queryBuilder);
  14. searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
  15. request.source(searchSourceBuilder);
  16. SearchResponse search = client.search(request, RequestOptions.DEFAULT);
  17. //打印结果
  18. for (SearchHit hit : search.getHits().getHits()) {
  19. System.out.println(hit.getSourceAsMap());
  20. }
  21. }