欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ElasticSearch简单入门(二)

程序员文章站 2022-07-05 08:04:18
...

IK分词器

前提: 默认ES中采用标准分词器进行分词,但这种方式并不适用于中文网站,因此需要修改ES对中文友好分词,从而达到更佳的搜索的效果,IK分词器就是一个较好的选择

本地安装IK

1、下载对应版本,一般IK分词器的版本与ElasticSearch的版本相对应
2、在glugins目录下创建个目录(名字随意),将IK的zip包放到该目录下,然后进行解压
- unzip elasticsearch-analysis-ik-6.8.0.zip
3、重启ES生效,会自动扫描glugins下的插件

测试

PUT /ems
{
  "mappings":{
    "emp":{
      "properties":{
        "name":{
          "type":"text",
           "analyzer": "ik_max_word",
           "search_analyzer": "ik_max_word"
        },
        "age":{
          "type":"integer"
        },
        "bir":{
          "type":"date"
        },
        "content":{
          "type":"text",
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_max_word"
        },
        "address":{
          "type":"keyword"
        }
      }
    }
  }
}


PUT /ems/emp/_bulk
  {"index":{}}
  {"name":"张学友","age":23,"bir":"2012-12-12","content":"为开发团队选择一款优秀的MVC框架是件难事儿,在众多可行的方案中决择需要很高的经验和水平","address":"北京"}
  {"index":{}}
  {"name":"刘德华","age":24,"bir":"2012-12-12","content":"Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式","address":"上海"}
  {"index":{}}
  {"name":"张学友的表弟","age":8,"bir":"2012-12-12","content":"Spring Cloud 作为Java 语言的微服务框架,它依赖于Spring Boot,有快速开发、持续交付和容易部署等特点。Spring Cloud 的组件非常多,涉及微服务的方方面面,井在开源社区Spring 和Netflix 、Pivotal 两大公司的推动下越来越完善","address":"无锡"}
  {"index":{}}
  {"name":"郭富城","age":9,"bir":"2012-12-12","content":"Spring的目标是致力于全方位的简化Java开发。 这势必引出更多的解释, Spring是如何简化Java开发的?","address":"南京"}
  {"index":{}}
  {"name":"黎明","age":43,"bir":"2012-12-12","content":"Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API","address":"杭州"}
  {"index":{}}
  {"name":"刘德华的表哥","age":59,"bir":"2012-12-12","content":"ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口","address":"北京"}


GET /ems/emp/_search
{
  "query":{
    "term":{
      "content":"框架"
    }
  }
}

Java操作ES

引入依赖

		<dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>6.8.0</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>6.8.0</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch.plugin</groupId>
            <artifactId>transport-netty4-client</artifactId>
            <version>6.8.0</version>
        </dependency>

1、创建客户端操作对象

//返回操作ES的TransportClient
    public PreBuiltTransportClient client() throws UnknownHostException {
        PreBuiltTransportClient client = new PreBuiltTransportClient(Settings.EMPTY);
        client.addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.1.21"), 9300));
        return client;
    }

2、创建索引

//创建索引
    @org.junit.Test
    public void test01() throws UnknownHostException, ExecutionException, InterruptedException {
        PreBuiltTransportClient client = client();

        //定义索引请求
        CreateIndexRequest ems = new CreateIndexRequest("dangdang");
        //执行创建索引的请求


        CreateIndexResponse createIndexResponse = client.admin().indices().create(ems).get();
        System.out.println(createIndexResponse.isAcknowledged());

    }

3、删除索引

 //删除索引
    @org.junit.Test
    public void test02() throws UnknownHostException, ExecutionException, InterruptedException {
        PreBuiltTransportClient client = client();

        //定义删除索引的请求
        DeleteIndexRequest ems = new DeleteIndexRequest("ems");

        AcknowledgedResponse acknowledgedResponse = client.admin().indices().delete(ems).get();
        System.out.println(acknowledgedResponse.isAcknowledged());
    }

4、创建索引和类型

 @org.junit.Test
    public void test03() throws UnknownHostException, ExecutionException, InterruptedException {
        PreBuiltTransportClient client = client();

        //创建索引
        CreateIndexRequest ems = new CreateIndexRequest("ems");

        //定义json格式映射
        String json = "{\"properties\":{\"name\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\"}," +
                "\"age\":{\"type\":\"integer\"},\"sex\":{\"type\":\"keyword\"}," +
                "\"content\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\"}}}";

        //设置类型和映射
        ems.mapping("emp", json, XContentType.JSON);

        //执行
        CreateIndexResponse createIndexResponse = client.admin().indices().create(ems).get();
        System.out.println(createIndexResponse.isAcknowledged());
    }

5、根据指定索引和类型下创建文档(指定ID)

 @org.junit.Test
    public void test04() throws UnknownHostException {

        PreBuiltTransportClient client = client();

        Emp emp = new Emp("张学友", 50, "男", "我是一个歌神");
        String s = JSONObject.toJSONString(emp);
        IndexResponse indexResponse = client.prepareIndex("ems", "emp", "1").setSource(s, XContentType.JSON).get();
        System.out.println(indexResponse.status());
    }

6、根据指定索引和类型下创建文档(自动生成ID)

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {
    private String name;
    private int age;
    private String sex;
    private  String content;
}

 @org.junit.Test
    public void test05() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        Emp emp = new Emp("刘德华", 100, "男", "我是一个影帝");

        String s = JSONObject.toJSONString(emp);
        IndexResponse indexResponse = client.prepareIndex("ems", "emp").setSource(s, XContentType.JSON).get();
        System.out.println(indexResponse.status());
    }

7、更新一条索引

 @org.junit.Test
    public void test06() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        Emp emp = new Emp();
        emp.setName("我是更新后的张学友");

        String s = JSONObject.toJSONString(emp);
        UpdateResponse updateResponse = client.prepareUpdate("ems", "emp", "1").setDoc(s, XContentType.JSON).get();
        System.out.println(updateResponse.status());

    }

8、删除一条索引

@org.junit.Test
    public void test07() throws UnknownHostException {
        PreBuiltTransportClient client = client();
        DeleteResponse deleteResponse = client.prepareDelete("ems", "emp", "C5OPgHYBuGfbHGEA7OWh").get();
        System.out.println(deleteResponse.status());
    }

查询操作

1、查询所有并排序

@org.junit.Test
    public void test09() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(QueryBuilders.matchAllQuery())
                .addSort("age", SortOrder.ASC)
                .get();

        SearchHits hits = searchResponse.getHits();
        System.out.println("符合的条数: " + hits.totalHits);

        for (SearchHit hit : hits
        ) {
            System.out.println("当前的索引分数:" + hit.getScore());
            System.out.println("对应的结果:" + hit.getSourceAsString());
        }

    }

2、分页查询

 @org.junit.Test
    public void test10() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(QueryBuilders.matchAllQuery())
                .setFrom(0)
                .setSize(3)
                .get();

        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits
        ) {
            System.out.println("对应的结果:" + hit.getSourceAsString());
        }
    }

3、返回指定的字段

 @org.junit.Test
    public void test11() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(QueryBuilders.matchAllQuery())
                .setFetchSource("*", "age")     //将age字段排除在外
                .get();

        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits
        ) {
            System.out.println("对应的结果:" + hit.getSourceAsString());
        }
    }

4、term查询

@org.junit.Test
    public void test12() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "张学友");
        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(termQueryBuilder)
                .get();
        System.out.println(searchResponse.getHits().getTotalHits());
    }

5、范围(range)查询

 @org.junit.Test
    public void test13() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").lt(22).gte(0);
        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(rangeQueryBuilder)
                .get();

        System.out.println(searchResponse.getHits().getTotalHits());
    }

6、prefix 查询

 @org.junit.Test
    public void test14() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("name", "张");
        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(prefixQueryBuilder)
                .get();

        System.out.println(searchResponse.getHits().getTotalHits());
    }

7、wildcard (通配符)查询

 @org.junit.Test
    public void test15() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("name", "张*");
        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(wildcardQueryBuilder)
                .get();

        System.out.println(searchResponse.getHits().getTotalHits());
    }

8、Ids 查询

 @org.junit.Test
    public void test16() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        IdsQueryBuilder idsQueryBuilder = QueryBuilders.idsQuery().addIds("1", "2");
        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(idsQueryBuilder)
                .get();

        System.out.println(searchResponse.getHits().getTotalHits());
    }

9、fuzzy 模糊查询

 @org.junit.Test
    public void test17() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("name", "张雪友");
        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(fuzzyQueryBuilder)
                .get();

        System.out.println(searchResponse.getHits().getTotalHits());
    }

10、bool 查询

@org.junit.Test
    public void test18() throws UnknownHostException {
        PreBuiltTransportClient client = client();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.should(QueryBuilders.matchAllQuery());
        boolQueryBuilder.mustNot(QueryBuilders.rangeQuery("age").lte(8));
        SearchResponse searchResponse = client.prepareSearch("ems")
                .setTypes("emp")
                .setQuery(boolQueryBuilder)
                .get();

        System.out.println(searchResponse.getHits().getTotalHits());
    }

SpringBoot操作ES

引入依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
 </dependency>

在SpringBoot中有两种方式(两个对象)来操作ES,一个是 RestHighLevelClient对象,一个是ElasticsearchRepository接口

RestHighLevelClient操作ES(适合进行复杂操作)

1、创建该对象的Bean,使用JavaConfig形式注入容器

@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {

    //这个client用来替换transportClient(9300)对象
    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
        //定义客户端配置对象   RestClient对象,端口号9200
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("192.168.1.21:9200")
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

2、删除指定ID

//第一种用法
    @Autowired
    private RestHighLevelClient restHighLevelClient;    //复杂查询使用    比如:高亮查询   指定条件查询


 @Test
    public void test01() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest("ems", "emp", "1");
        DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }

3、创建指定文档

 @Test
    public void test02() throws IOException {

        IndexRequest indexRequest = new IndexRequest("ems", "emp", "3");
        indexRequest.source("{\"name\":\"小黑\",\"age\":\"66\"}", XContentType.JSON);

        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }

4、查询所有

 @Test
    public void test03() throws IOException {
        SearchRequest request = new SearchRequest("ems");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        request.types("emp").source(searchSourceBuilder);
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit:hits
             ) {
            System.out.println(hit.getSourceAsString());
        }
        // System.out.println(response.getHits().getTotalHits());
    }

5、修改文档

 @Test
    public void test04() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("ems", "emp", "3");
        updateRequest.doc("{\"name\":\"修改后的小黑\",\"age\":88}",XContentType.JSON);
        UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }

6、多条操作进行

	@Test
    public void test05() throws IOException {

        BulkRequest bulkRequest = new BulkRequest();

        //添加
        IndexRequest indexRequest = new IndexRequest("ems", "emp", "4");
        indexRequest.source("{\"name\":\"小白\",\"age\":\"167\"}", XContentType.JSON);
        //删除
        //修改
        bulkRequest.add(indexRequest);
        BulkResponse responses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        BulkItemResponse[] items = responses.getItems();
        for (BulkItemResponse item:items
             ) {
            System.out.println(item.status());
        }
    }

7、复杂查询-----分页查询并排序

 @Test
    public void test07() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置查询的条件
        searchSourceBuilder.from(0).size(2).sort("age", SortOrder.DESC).query(QueryBuilders.matchAllQuery());
        //设置查询的索引和类型
        searchRequest.indices("ems")
                .types("emp")
                .source(searchSourceBuilder);

        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit:hits
             ) {
            System.out.println(hit.getSourceAsString());
        }
    }

8、复杂查询-----高亮查询

 @Test
    public void test08() throws IOException {
        SearchRequest request = new SearchRequest();
        SearchSourceBuilder builder = new SearchSourceBuilder();
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("content")
                .requireFieldMatch(false)
                .preTags("<span style='color:red;'>")
                .postTags("</span>");

       builder.from(0).size(2)
               .sort("age",SortOrder.DESC)
               .highlighter(highlightBuilder)
               .query(QueryBuilders.termQuery("content","我是"));
       request.indices("ems").types("emp").source(builder);

        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit:hits
             ) {
            System.out.println(hit.getSourceAsString());
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            highlightFields.forEach((k,v) -> System.out.println("key:"+k+"value:"+v.fragments()[0]));
        }
    }

ElasticsearchRepository接口方式操作(适合简单操作)

1、创建Entity

@Document(indexName = "dangdang",type = "book")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {

    @Id
    private String id;
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    private String name;
    @Field(type = FieldType.Date)
    private Date createDate;
    @Field(type = FieldType.Keyword)
    private String author;
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    private String content;
}

2、编写BookRepository

public interface BookRepository extends ElasticsearchRepository<Book,String> {

}

3、添加文档

@Autowired
    private BookRepository bookRepository;     //使用该对象进行CRUD的相关操作

    //添加索引和更新索引id   存在更新  不存在则添加
    @Test
    public void test01(){
        Book book = new Book();
        book.setId("21");
        book.setName("小颜");
        book.setCreateDate(new Date());
        book.setAuthor("吴亦凡");
        book.setContent("这是我的一本新书");

        Book book2 = new Book();
        book2.setId("100");
        book2.setName("小闫");
        book2.setCreateDate(new Date());
        book2.setAuthor("朴宰范");
        book2.setContent("这是我的烫嘴rap");

        bookRepository.save(book);
        bookRepository.save(book2);

    }

4、删除一条记录

 @Test
    public void test02(){
        Book book = new Book();
        book.setId("21");
        bookRepository.delete(book);
    }

5、查询所有

 @Test
    public void test03(){
        Iterable<Book> all = bookRepository.findAll();
        for (Book book: all
             ) {
            System.out.println(book);
        }
    }

6、查询指定ID

@Test
    public void test04(){

        Optional<Book> book = bookRepository.findById("21");
        System.out.println(book.get());
    }

7、排序查询

@Test
    public  void test05(){
        Iterable<Book> books = bookRepository.findAll(Sort.by(Sort.Order.desc("createDate")));
        for (Book book:books
             ) {
            System.out.println(book);
        }
    }