全文檢索 — ElasticSearch_02(ES編程操作:創建索引、設置mapping、添加文檔、查詢文檔、分頁操作、高亮顯示)


歡迎訪問筆者個人技術博客:http://rukihuang.xyz/

一、ES編程操作

1.1 導入依賴座標

  • pom.xml。本文使用的ES版本爲5.6.8
<dependencies>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>5.6.8</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>5.6.8</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-to-slf4j</artifactId>
        <version>2.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.24</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.21</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

1.2 創建索引index

  • 創建索引的步驟
    1. 創建一個Settings對象,相當於是一個配置信息。主要配置集羣的名稱。
    2. 創建一個客戶端Client對象
    3. 使用client對象創建一個索引庫
    4. 關閉client對象
@Test
public void createIndex() throws UnknownHostException {
    //1、創建一個Settings對象,相當於是一個配置信息。主要配置集羣的名稱。
    Settings settings = Settings.builder()
        .put("cluster.name", "my-elasticsearch")
        .build();
    //2、創建一個客戶端Client對象
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(
        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300))
        .addTransportAddress(
        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
        .addTransportAddress(
        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));
    //3、使用client對象創建一個索引庫
    client.admin().indices().prepareCreate("blog").get();
    //4、關閉client對象
    client.close();
}

在這裏插入圖片描述

1.3 創建映射mapping

  • 創建設置映射的步驟
    1. 創建一個Settings對象
    2. 創建一個Client對象
    3. 創建一個mapping信息,應該是一個json數據,可以是字符串,也可以是XContextBuilder對象
    4. 使用client向es服務器發送mapping信息
    5. 關閉client對象
    @Test
    public void setMappings() throws IOException {
        //1)創建一個Settings對象
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        //2)創建一個Client對象
        TransportClient client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));

        //3)創建一個mapping信息,應該是一個json數據,可以是字符串,也可以是XContextBuilder對象
/*        {
            "article":{
                "properties":{
                    "id":{
                        "type":"long",
                        "index":"not_analyzed",
                        "store":true
                    }
                    "title":{
                        "type":"text",
                        "store":true,
                        "index":"analyzed",
                        "analyzer":"ik_smart"
                    }
                    "content":{
                        "type":"text",
                        "store":true,
                        "index":"analyzed",
                        "analyzer":"ik_smart"
                    }
                }
            }
        }*/
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                    .startObject("article")
                        .startObject("properties")
                            .startObject("id")
                                .field("type", "long")
                                .field("index", "not_analyzed")
                                .field("store", true)
                            .endObject()
                            .startObject("title")
                                .field("type", "text")
                                .field("store", true)
                                .field("index", "analyzed")
                                .field("analyzer", "ik_smart")
                            .endObject()
                            .startObject("content")
                                .field("type", "text")
                                .field("store", "true")
                                .field("index", "analyzed")
                                .field("analyzer", "ik_smart")
                            .endObject()
                        .endObject()
                    .endObject()
                .endObject();

        //4)使用client向es服務器發送mapping信息
        client.admin().indices().preparePutMapping("blog").setType("article").setSource(builder).get();
        //5)關閉client對象
        client.close();
    }
  • 注意:startObject()表示一個左大括號{endObject()表示一個右大括號}

在這裏插入圖片描述

1.4 建立添加文檔document

1.4.1 XContentBuilder

  • 步驟
    1. 創建一個Settings對象
    2. 創建一個Client對象
    3. 創建一個文檔對象,創建一個json格式的字符串,或者使用XContentBuilder
    4. 使用Client對象吧文檔添加到索引庫中
    5. 關閉client
    @Test
    public void testAddDocument() throws IOException {
        //1. 創建一個client對象
        //2. 創建一個文檔對象
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                    .field("id", "1")
                    .field("title", "讓民營企業創造活力迸發")
                    .field("content", "民營經濟是社會主義市場經濟發展的重要成果,是推動經濟社會發展的重要力量。")
                .endObject();
        //3. 把文檔添加到索引庫
//        client.prepareIndex("blog", "article", "1").setSource(builder).get();
        client.prepareIndex()
                //設置索引
                .setIndex("blog")
                //設置type
                .setType("article")
                //設置id,如果不設置的話生成一個Id
                .setId("1")
                //設置文檔信息
                .setSource(builder)
                //執行操作
                .get();
        //4. 關閉客戶端
        client.close();
    }

1.4.2 使用Jackson將實體轉爲Json

  • 步驟

    1. 創建一個pojo類
    2. 使用工具類把pojo轉換成json字符串
    3. 把文檔寫入索引庫
  • 首先要創建實體類

public class Article {
    private long id;
    private String title;
    private String content;
}
  • 添加jackson依賴座標
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.8.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.8.1</version>
</dependency>
  • 代碼實現
@Test
public void testAddDocument2() throws JsonProcessingException {
    //創建一個pojo類
    Article article = new Article();
    article.setId(2l);
    article.setTitle("中央出臺支持民營企業28條");
    article.setContent("《中共中央 國務院關於營造更好發展環境支持民營企業改革發展的意見》(以下簡稱《意見》)22日對外發布。意見提出優化公平競爭的市場環境,進一步放開民營企業市場準入,並提出一系列有針對性的舉措,爲民營企業參與市場競爭鬆綁開路,爲企業改革發展壯大拓展空間。");
    //使用工具類把pojo轉換成json字符串
    ObjectMapper mapper = new ObjectMapper();
    String jsonDocument = mapper.writeValueAsString(article);
    System.out.println(jsonDocument);
    //把文檔寫入索引庫
    client.prepareIndex("blog", "article", "2")
        .setSource(jsonDocument, XContentType.JSON)
        .get();
    //關閉客戶端
    client.close();
}

1.5 查詢文檔操作

  • 查詢步驟
    1. 創建一個Client對象
    2. 創建一個查詢對象,可以使用QueryBuilders工具類創建QueryBuilder對象。
    3. 使用client執行查詢
    4. 得到查詢的結果。
    5. 取查詢結果的總記錄數
    6. 取查詢結果列表
    7. 關閉client

1.5.0 創建客戶端對象client(@Before)

    @Before
    public void init() throws UnknownHostException {
        //1、創建一個Settings對象,相當於是一個配置信息。主要配置集羣的名稱。
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        //2、創建一個客戶端Client對象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(
                        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300))
                .addTransportAddress(
                        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
                .addTransportAddress(
                        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));
    }

1.5.1 id查詢

  • QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1", "2");
@Test
public void testQueryById() {
    //1)創建一個Client對象
    //2)創建一個查詢對象,可以使用QueryBuilders工具類創建QueryBuilder對象。
    QueryBuilder builder = QueryBuilders.idsQuery().addIds("1", "2");

    //3)使用client執行查詢
    SearchResponse searchResponse = client.prepareSearch("blog")
        .setTypes("article")
        .setQuery(builder)
        .get();
    //4)得到查詢的結果。
    SearchHits hits = searchResponse.getHits();
    //5)取查詢結果的總記錄數
    System.out.println("查詢的總記錄數:" + hits.getTotalHits());
    //6)取查詢結果列表
    Iterator<SearchHit> iterator = hits.iterator();
    while (iterator.hasNext()) {
        SearchHit searchHit = iterator.next();
        //以Json格式輸出
        System.out.println(searchHit.getSourceAsString());
        //取文檔的屬性
        Map<String, Object> document = searchHit.getSource();
        System.out.println(document.get("id"));
        System.out.println(document.get("title"));
        System.out.println(document.get("content"));
    }
    //7)關閉client
    client.close();
}

1.5.2 關鍵詞查詢

  • QueryBuilder queryBuilder = QueryBuilders.termQuery("title", "北方");
@Test
public void testQueryByTerm() {
    //創建QueryBuilder對象
    //參數1:要搜索的字段
    //參數2:要搜索的關鍵詞
    QueryBuilder builder = QueryBuilders.termQuery("title", "中央");
    //執行查詢
    search(builder);
}

private void search(QueryBuilder builder) {
    //3)使用client執行查詢
    SearchResponse searchResponse = client.prepareSearch("blog")
        .setTypes("article")
        .setQuery(builder)
        .get();
    //4)得到查詢的結果。
    SearchHits hits = searchResponse.getHits();
    //5)取查詢結果的總記錄數
    System.out.println("查詢的總記錄數:" + hits.getTotalHits());
    //6)取查詢結果列表
    Iterator<SearchHit> iterator = hits.iterator();
    while (iterator.hasNext()) {
        SearchHit searchHit = iterator.next();
        //以Json格式輸出
        System.out.println(searchHit.getSourceAsString());
        //取文檔的屬性
        Map<String, Object> document = searchHit.getSource();
        System.out.println(document.get("id"));
        System.out.println(document.get("title"));
        System.out.println(document.get("content"));
    }
    //7)關閉client
    client.close();
}

1.5.3 字符串查詢

  • QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("速度與激情").defaultField("title");
@Test
public void testQueryStirng() {
    //創建QueryBuilder對象
    QueryBuilder builder = QueryBuilders.queryStringQuery("中央").defaultField("title");
    //執行查詢
    search(builder);
}

1.6 查詢文檔分頁操作

  • client.prepareSearch("blog").setTypes("article").setQuery(builder).setFrom(0).setSize(5).get();

  • 設置setFromsetSize

    private void search(QueryBuilder builder) {
        //3)使用client執行查詢
        SearchResponse searchResponse = client.prepareSearch("blog")
                .setTypes("article")
                .setQuery(builder)
            	//設置分頁信息 --------------!
                .setFrom(0)
                //每頁顯示的行數 ------------!
                .setSize(5)
                .get();
        //4)得到查詢的結果。
        SearchHits hits = searchResponse.getHits();
        //5)取查詢結果的總記錄數
        System.out.println("查詢的總記錄數:" + hits.getTotalHits());
        //6)取查詢結果列表
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()) {
            SearchHit searchHit = iterator.next();
            //以Json格式輸出
            System.out.println(searchHit.getSourceAsString());
            //取文檔的屬性
            Map<String, Object> document = searchHit.getSource();
            System.out.println(document.get("id"));
            System.out.println(document.get("title"));
            System.out.println(document.get("content"));
        }
        //7)關閉client
        client.close();
    }

1.7 查詢結果高亮顯示

  • 原理:將查詢出來的結果用html標籤包圍
    • new一個HighlighterBuilder,設置高亮字段和要包裹的html標籤
    • client.prepareSearch()設置.highlighter(highlighterBuilder)\
    //高亮查詢
    private void search(QueryBuilder builder, String highlightField) {
        HighlightBuilder highlightBuilder = new HighlightBuilder();//---!
        //高亮顯示的字段
        highlightBuilder.field(highlightField);//-----------------------!
        highlightBuilder.preTags("<em>");//-----------------------------!
        highlightBuilder.postTags("</em>");//---------------------------!
        //3)使用client執行查詢
        SearchResponse searchResponse = client.prepareSearch("blog")
                .setTypes("article")
                .setQuery(builder)
                //設置分頁信息
                .setFrom(0)
                //每頁顯示的行數
                .setSize(5)
                .highlighter(highlightBuilder)//------------------------!
                .get();
        //4)得到查詢的結果。
        SearchHits hits = searchResponse.getHits();
        //5)取查詢結果的總記錄數
        System.out.println("查詢的總記錄數:" + hits.getTotalHits());
        //6)取查詢結果列表
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()) {
            SearchHit searchHit = iterator.next();
            //以Json格式輸出
            System.out.println(searchHit.getSourceAsString());
            //取文檔的屬性
            System.out.println("-----------------文檔屬性--------------");
            Map<String, Object> document = searchHit.getSource();
            System.out.println(document.get("id"));
            System.out.println(document.get("title"));
            System.out.println(document.get("content"));
            System.out.println("-----------------高亮區域--------------");
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            System.out.println(highlightFields);
            //取高亮顯示的結果
            HighlightField field = highlightFields.get("title");
            Text[] fragments = field.getFragments(); //一般來說每一條結果都只有一個title,索引取第一個就行
            if (fragments != null) { //判斷結果是否爲Null
                String title = fragments[0].toString();
                System.out.println(title);
            }
        }
        //7)關閉client
        client.close();
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章