1. 程式人生 > 其它 >ElasticSearch簡單入門(二)

ElasticSearch簡單入門(二)

技術標籤:ElasticSearchelasticsearchjava

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);
        }
    }