Bootstrap

Elasticsearch 实战

Elasticsearch 实战

创建资源的方式

  • 基于 REST 风格的 HTTP 请求

    是否使用REST获取用户信息删除用户信息更新用户信息保存用户信息
    /getUser/deleteUser/updateUser/saveUser
    /user method=GET/user method=DELETE/user method=PUT/user method=POST
  • ES 基于 REST 风格的指令

    method请求url描述
    PUT/POST(创建,修改)localhost:9200/索引名称/类型名称/文档id创建文档(指定doc_id)
    POST(创建)localhost:9200/索引名称/类型名称创建文档(随机doc_id)
    POST(修改)localhost:9200/索引名称/类型名称/文档id/_update修改文档
    DELETE(删除)localhost:9200/索引名称/类型名称/文档id删除文档
    GET(查询)localhost:9200/索引名称/类型名称/文档id通过doc_id查询文档
    POST(查询)localhost:9200/索引名称/类型名称/文档id/_search根据条件查询

操作内容

  • 创建索引

    • 不指定字段类型映射

      PUT/user_no_mappings
      

在这里插入图片描述

在这里插入图片描述

```json
PUT /student/type1/001
{
  "name": "wanji",
  "age": 20,
  "city": "北京"
}
```

在这里插入图片描述
在这里插入图片描述

  • 指定字段类型映射

    PUT /user_mappings1
    {
      "mappings": {
        "properties": {
          "name": {
            "type": "text"
          },
          "age": {
            "type": "long"
          }
        }
      }
    }
    

在这里插入图片描述
在这里插入图片描述

  • 创建文档

    • 指定文档id

      PUT /student/type1/001
      {
        "name": "wanji",
        "age": 20,
        "city": "北京"
      }
      
      POST /student/type1/003
      {
        "name": "Bob",
        "age": 18,
        "city": "北京"
      }
      
      

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 随机id

    POST /student/type1
    {
      "name": "Tony",
      "age": 10,
      "city": "深圳"
    }
    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 查询信息

    • 查询索引信息

      GET /student
      

在这里插入图片描述

  • 查询文档信息

    通过_index+_type+_id就可以唯一标识一条文档
    GET /student/type1/001
    

在这里插入图片描述

  • 不同分词器下的条件索引

    GET /student/type1/_search?q=name:wanji001
    
    GET /student/type1/_search?q=name:wanji
    
    PUT /user_ik
    {
      "mappings": {
        "properties": {
          "name": {
            "type": "text",
            "analyzer": "ik_max_word"
          },
          "age": {
            "type": "long"
          }
        }
      }
    }
    
    PUT user_ik/_doc/001
    {
      "name": "wanji001",
      "age":10
    }
    
    GET /user_ik/_doc/_search?q=name:wanji
    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 复杂条件搜索

    GET /user_ik/_doc/_search
    {
      "query": {
        "match": {
          "name": "wanji"
        }
      }
    }
    

在这里插入图片描述

    //创建book
    PUT /book
    {
      "mappings": {
        "properties": {
          "name": {
            "type": "text",
            "analyzer": "ik_max_word"
          },
          "age": {
            "type": "long"
          }
        }
      }
    }
    //加入数据
    PUT /book/_doc/001
    {
      "name": "Java编程思想",
      "price":100,
      "tags":[
          "Java","经典","入门","语言"
        ]
    }
    
    PUT /book/_doc/002
    {
      "name": "SpringBoot编程思想",
      "price":110,
      "tags":[
          "SpringBoot","Spring","新书"
        ]
    }
    
    PUT /book/_doc/003
    {
      "name": "Spring源码深度解析",
      "price":100,
      "tags":[
          "源码","Spring","进阶"
        ]
    }
    
    PUT /book/_doc/004
    {
      "name": "实战Java虚拟机",
      "price":70,
      "tags":[
          "Java","JNVM","虚拟机","经典"
        ]
    }
    
    PUT /book/_doc/005
    {
      "name": "Effective",
      "price":80,
      "tags":[
          "Java","优化","英文","经典"
        ]
    }

在这里插入图片描述

1>指定需要展示的列
GET /book/_doc/_search
{
  "query": {
    "match": {
      "name": "Java"
    }
  },
  "_source":["name","price"]
}

在这里插入图片描述

2>多个内容搜索

GET /book/_doc/_search
{
  "query": {
    "match": {
      "tags": "英文 经典"
    }
  }
}

在这里插入图片描述

3>对结果进行搜索

GET /book/_doc/_search
{
  "query": {
    "match": {
      "name": "Java"
    }
  },
  "sort": {
    "price": {
      "order": "desc"
    }
  }
}

在这里插入图片描述

4>分页展示

GET /book/_doc/_search
{
  "query": {
    "match": {
      "name": "Java"
    }
  },
  "from":1,
  "size":1
}

在这里插入图片描述

5>bool 查询

​	and 查询

GET /book/_doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "Java"
          }
        },
        {
          "match": {
            "price":"100"
          }
        }
        ]
    }
  }
}

在这里插入图片描述

​	or 查询

GET /book/_doc/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "Java"
          }
        },
        {
          "match": {
            "price":100
          }
        }
        ]
    }
  }
}

在这里插入图片描述

​	非操作

GET /book/_doc/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "name": "Java"
          }
        }
        ]
    }
  }
}

在这里插入图片描述

​	结果过滤

GET /book/_doc/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "Java"
          }
        },
        {
          "match": {
            "price": "100"
          }
        }
        ],
        "filter": {
          "range": {
            "price": {
              "gte":80,
              "lte":100
            }
          }
        }
    }
  }
}

在这里插入图片描述

  • 高亮查询

    GET /book/_doc/_search
    {
      "query": {
        "match": {
          "name": "Java"
        }
      },
      "highlight": {
        "fields": {
          "name":{}
        }
      }
    }
    
    

在这里插入图片描述

```json
GET /book/_doc/_search
{
  "query": {
    "match": {
      "name": "Java"
    }
  },
  "highlight": {
    "pre_tags": "<wanji>",
    "post_tags":"</wanji>",
    "fields": {
      "name":{}
    }
  }
}
```

在这里插入图片描述

  • 通过_cat查询ES信息(可私信获取,内容过多,有文档)

  • 修改数据

    • 覆盖修改

      PUT /student/type1/001
      {
        "name":"wanji",
        "age": 20,
        "city": "北京"
      }
      
      
      

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 非覆盖修改

    POST /student/type1/002/_update
    {
      "doc": {
        "name": "Tom001"
      }
    }
    

在这里插入图片描述
在这里插入图片描述

  • 删除数据

    • 删除文档

      DELETE student/type1/001
      

在这里插入图片描述

  • 删除索引

    DELETE booktest
    

在这里插入图片描述

  • 与 SpringBoot 进行集成开发

    • 创建 ESClientConfig 类

      @Configuration
      public class ESClientConfig {
          private final static String HOST_NAME = "127.0.0.1";
          private final static int PORT = 9200;
          private final static String SCHEME = "http";
      
          @Bean
          public RestHighLevelClient restHighLevelClient() {
              HttpHost httpHost = new HttpHost(HOST_NAME, PORT, SCHEME);
              RestClientBuilder builder = RestClient.builder(httpHost);
              RestHighLevelClient client = new RestHighLevelClient(builder);
              return client;
          }
      }
      
    • 创建实体类

      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      public class Book {
      
          private String name;
      
          private Integer price;
      
          private List<String> tags;
      }
      
    • test 测试类

      @Slf4j
      @SpringBootTest
      class ElasticsearchDemoApplicationTests {
      
          private final static String INDEX_NAME = "springboot-demo";
      
          @Resource
          private RestHighLevelClient restHighLevelClient;
      
          private static Gson gson = new Gson();
      
          /**
           * 创建索引 CreateIndexRequest
           */
          @Test
          void createIndex() throws Throwable {
              CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);
              restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
          }
      
          /**
           * 获取索引 GetIndexRequest
           */
          @Test
          void getIndex() throws Throwable {
              GetIndexRequest request = new GetIndexRequest(INDEX_NAME);
              GetIndexResponse response = restHighLevelClient.indices().get(request, RequestOptions.DEFAULT);
              log.info("mappings={} \n settings={}", gson.toJson(response.getMappings()),
                      gson.toJson(response.getSettings()));
          }
      
          /**
           * 判断索引是否存在 GetIndexRequest
           */
          @Test
          void existIndex() throws Throwable {
              GetIndexRequest request = new GetIndexRequest(INDEX_NAME);
              boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
              log.info("exists={}", exists);
          }
      
          /**
           * 删除索引 DeleteIndexRequest
           */
          @Test
          void deleteIndex() throws Throwable {
              DeleteIndexRequest request = new DeleteIndexRequest(INDEX_NAME);
              AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
              log.info("isAcknowledged={}" + response.isAcknowledged());
          }
      
          /**
           * 创建文档 IndexRequest
           */
          @Test
          void createDoc() throws Throwable {
              IndexRequest request = new IndexRequest(INDEX_NAME);
      
              // 方式一:采用对象转Gson的方式创建文档
              Book book = new Book("Java编程思想", 100, Lists.newArrayList("Java", "经典", "入门", "语言"));
              request.id("001");
              request.timeout(TimeValue.timeValueSeconds(5));
              request.source(gson.toJson(book), Requests.INDEX_CONTENT_TYPE);
              IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
              log.info("response={}", response);
      
              // 方式二:采用逐一传参的方式创建文档
              request.id("002");
              request.timeout(TimeValue.timeValueSeconds(5));
              request.source("name", "Spring Boot编程思想", "price", 110, "tags", Lists.newArrayList("SpringBoot",
                      "Spring", "新书"));
              response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
              log.info("response={}", response);
      
              // 方式三:批量创建文档
              List<Book> books = Lists.newArrayList(new Book("a", 1, Lists.newArrayList("a1")),
                      new Book("b", 2, Lists.newArrayList("b2")),
                      new Book("c", 3, Lists.newArrayList("c3")),
                      new Book("d", 4, Lists.newArrayList("d4")));
              BulkRequest bulkRequest = new BulkRequest(INDEX_NAME);
              AtomicInteger id = new AtomicInteger(1);
              books.stream().forEach(b -> bulkRequest.add(
                      new IndexRequest(INDEX_NAME)
                              .id(String.valueOf(id.getAndIncrement())) // 指定文档id,不指定则取默认值
                              .source(gson.toJson(b), Requests.INDEX_CONTENT_TYPE)));
      
              BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
              log.info("bulkInsert is success={}", !bulkResponse.hasFailures());
          }
      
          /**
           * 获取文档 GetRequest
           */
          @Test
          void getDoc() throws Throwable {
              GetRequest request = new GetRequest(INDEX_NAME, "001");
              boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
              log.info("exists={}", exists);
      
              GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
              log.info("response={} \n source={}", gson.toJson(response), response.getSourceAsString());
          }
      
          /**
           * 更新文档 UpdateRequest
           */
          @Test
          void updateDoc() throws Throwable {
              // 方法一:直接修改响应属性
              UpdateRequest request = new UpdateRequest(INDEX_NAME, "001");
              request.doc("name", "Java编程思想最新版");
              UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
              log.info("status={}", response.status());
      
              // 方式二:Gson方式更新
              Book book = new Book("Spring Boot编程思想", 110, Lists.newArrayList("SpringBoot", "Spring",
                      "新书")); // 这个book对象,应该从ES中获取;为了方便,此处我就直接new了
              book.setName("Spring Boot编程思想最新版");
              request = new UpdateRequest(INDEX_NAME, "002");
              request.doc(gson.toJson(book), Requests.INDEX_CONTENT_TYPE);
              response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
              log.info("status={}", response.status());
          }
      
          /**
           * 搜索文档 SearchRequest
           */
          @Test
          void searchDoc() throws Throwable {
              SearchRequest request = new SearchRequest(INDEX_NAME);
              SearchSourceBuilder builder = new SearchSourceBuilder();
              builder.timeout(TimeValue.timeValueSeconds(10));
              builder.query(QueryBuilders.matchQuery("name", "思想"));
              // builder.query(QueryBuilders.termQuery("name", "思想"));
              builder.from(0);
              builder.size(10);
              builder.highlighter(new HighlightBuilder().field("name").preTags("<muse>").postTags("</muse>")); // 高亮
              request.source(builder);
              SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
              Arrays.stream(response.getHits().getHits()).forEach(System.out::println);
          }
      
          /**
           * 删除文档 DeleteRequest
           */
          @Test
          void deleteDoc() throws Throwable {
              DeleteRequest request = new DeleteRequest(INDEX_NAME, "001");
              DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
              log.info("status={}", response.status());
          }
      }
      
;