搜尋引擎ElasticSearch18_ElasticSearch程式設計操作5

花溪月影發表於2024-05-27

一、建立工程,匯入座標

 pom.xml座標

<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>

二、建立索引index

@Test
//建立索引
public void test1() throws Exception{
    // 建立Client連線物件
    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    //建立名稱為blog2的索引
    client.admin().indices().prepareCreate("blog2").get();
    //釋放資源
    client.close();
}

   

三、建立對映mapping

@Test
//建立對映
public void test3() throws Exception{
    // 建立Client連線物件
    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
    
    // 新增對映
    /**
         * 格式:
         * "mappings" : {
             "article" : {
                "dynamic" : "false",
                 "properties" : {
                    "id" : { "type" : "string" },
                     "content" : { "type" : "string" },
                    "author" : { "type" : "string" }
                 }
            }
         }
         */
    XContentBuilder builder = XContentFactory.jsonBuilder()
        .startObject()
        .startObject("article")
        .startObject("properties")
        .startObject("id")
        .field("type", "integer").field("store", "yes")
        .endObject()
        .startObject("title")
        .field("type", "string").field("store", "yes").field("analyzer", "ik_smart")
        .endObject()
        .startObject("content")
        .field("type", "string").field("store", "yes").field("analyzer", "ik_smart")
        .endObject()
        .endObject()
        .endObject()
        .endObject();
    // 建立對映
    PutMappingRequest mapping = Requests.putMappingRequest("blog2")
        .type("article").source(builder);
    client.admin().indices().putMapping(mapping).get();
    //釋放資源
    client.close();
}

   

四、建立文件document

 1、建立文件(透過XContentBuilder)

@Test
//建立文件(透過XContentBuilder)
public void test4() throws Exception{
    // 建立Client連線物件
    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

    //建立文件資訊
    XContentBuilder builder = XContentFactory.jsonBuilder()
        .startObject()
        .field("id", 1)
        .field("title", "ElasticSearch是一個基於Lucene的搜尋伺服器")
        .field("content",
               "它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放原始碼釋出,是當前流行的企業級搜尋引擎。設計用於雲端計算中,能夠達到實時搜尋,穩定,可靠,快速,安裝使用方便。")
        .endObject();

    // 建立文件物件
    /**
         * 引數一blog1:表示索引物件
         * 引數二article:型別
         * 引數三1:建立id
         */
    client.prepareIndex("blog2", "article", "1").setSource(builder).get();

    //釋放資源
    client.close();
}

  

 2、建立文件(使用Jackson轉換實體)

  1)建立Article實體

public class Article {
    private Integer id;
    private String title;
    private String content;
    getter/setter...
}

  2)新增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>

  3)程式碼實現

@Test
//建立文件(透過實體轉json)
public void test5() throws Exception{
    // 建立Client連線物件
    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

    // 描述json 資料
    //{id:xxx, title:xxx, content:xxx}
    Article article = new Article();
    article.setId(2);
    article.setTitle("搜尋工作其實很快樂");
    article.setContent("我們希望我們的搜尋解決方案要快,我們希望有一個零配置和一個完全免費的搜尋模式,我們希望能夠簡單地使用JSON透過HTTP的索引資料,我們希望我們的搜尋伺服器始終可用,我們希望能夠一臺開始並擴充套件到數百,我們要實時搜尋,我們要簡單的多租戶,我們希望建立一個雲的解決方案。Elasticsearch旨在解決所有這些問題和更多的問題。");

    ObjectMapper objectMapper = new ObjectMapper();

    // 建立文件
    client.prepareIndex("blog2", "article", article.getId().toString())
        //.setSource(objectMapper.writeValueAsString(article)).get();
        .setSource(objectMapper.writeValueAsString(article).getBytes(), XContentType.JSON).get();

    //釋放資源
    client.close();
}

   

五、查詢文件操作

 1、關鍵詞查詢

@Test
public void testTermQuery() throws Exception{
    //1、建立es客戶端連線物件
    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

    //2、設定搜尋條件
    SearchResponse searchResponse = client.prepareSearch("blog2")
        .setTypes("article")
        .setQuery(QueryBuilders.termQuery("content", "搜尋")).get();

    //3、遍歷搜尋結果資料
    SearchHits hits = searchResponse.getHits(); // 獲取命中次數,查詢結果有多少物件
    System.out.println("查詢結果有:" + hits.getTotalHits() + "條");
    Iterator<SearchHit> iterator = hits.iterator();
    while (iterator.hasNext()) {
        SearchHit searchHit = iterator.next(); // 每個查詢物件
        System.out.println(searchHit.getSourceAsString()); // 獲取字串格式列印
        System.out.println("title:" + searchHit.getSource().get("title"));
    }

    //4、釋放資源
    client.close();

}

 2、字串查詢

@Test
public void testStringQuery() throws Exception{
    //1、建立es客戶端連線物件
    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

    //2、設定搜尋條件
    SearchResponse searchResponse = client.prepareSearch("blog2")
        .setTypes("article")
        .setQuery(QueryBuilders.queryStringQuery("搜尋")).get();

    //3、遍歷搜尋結果資料
    SearchHits hits = searchResponse.getHits(); // 獲取命中次數,查詢結果有多少物件
    System.out.println("查詢結果有:" + hits.getTotalHits() + "條");
    Iterator<SearchHit> iterator = hits.iterator();
    while (iterator.hasNext()) {
        SearchHit searchHit = iterator.next(); // 每個查詢物件
        System.out.println(searchHit.getSourceAsString()); // 獲取字串格式列印
        System.out.println("title:" + searchHit.getSource().get("title"));
    }

    //4、釋放資源
    client.close();

}

 3、使用文件ID查詢文件

@Test
    public void testIdQuery() throws Exception {
        //client物件為TransportClient物件
        SearchResponse response = client.prepareSearch("blog1")
                .setTypes("article")
                //設定要查詢的id
                .setQuery(QueryBuilders.idsQuery().addIds("test002"))
                //執行查詢
                .get();
        //取查詢結果
        SearchHits searchHits = response.getHits();
        //取查詢結果總記錄數
        System.out.println(searchHits.getTotalHits());
        Iterator<SearchHit> hitIterator = searchHits.iterator();
        while(hitIterator.hasNext()) {
            SearchHit searchHit = hitIterator.next();
            //列印整行資料
            System.out.println(searchHit.getSourceAsString());
        }
    }

六、查詢文件分頁操作

 1、批次插入資料

 @Test
//批次插入100條資料
public void test9() throws Exception{
        // 建立Client連線物件
        Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
        TransportClient client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

        ObjectMapper objectMapper = new ObjectMapper();

        for (int i = 1; i <= 100; i++) {
            // 描述json 資料
            Article article = new Article();
            article.setId(i);
            article.setTitle(i + "搜尋工作其實很快樂");
            article.setContent(i
                    + "我們希望我們的搜尋解決方案要快,我們希望有一個零配置和一個完全免費的搜尋模式,我們希望能夠簡單地使用JSON透過HTTP的索引資料,我們希望我們的搜尋伺服器始終可用,我們希望能夠一臺開始並擴充套件到數百,我們要實時搜尋,我們要簡單的多租戶,我們希望建立一個雲的解決方案。Elasticsearch旨在解決所有這些問題和更多的問題。");

            // 建立文件
            client.prepareIndex("blog2", "article", article.getId().toString())
                    //.setSource(objectMapper.writeValueAsString(article)).get();
                    .setSource(objectMapper.writeValueAsString(article).getBytes(),XContentType.JSON).get();
        }

        //釋放資源
        client.close();
}

  

 2、分頁查詢

@Test
//分頁查詢
public void test10() throws Exception{
    // 建立Client連線物件
    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

    // 搜尋資料
    SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2").setTypes("article")
        .setQuery(QueryBuilders.matchAllQuery());//預設每頁10條記錄

    // 查詢第2頁資料,每頁20條
    //setFrom():從第幾條開始檢索,預設是0。
    //setSize():每頁最多顯示的記錄數。
    searchRequestBuilder.setFrom(0).setSize(5);
    SearchResponse searchResponse = searchRequestBuilder.get();

    SearchHits hits = searchResponse.getHits(); // 獲取命中次數,查詢結果有多少物件
    System.out.println("查詢結果有:" + hits.getTotalHits() + "條");
    Iterator<SearchHit> iterator = hits.iterator();
    while (iterator.hasNext()) {
        SearchHit searchHit = iterator.next(); // 每個查詢物件
        System.out.println(searchHit.getSourceAsString()); // 獲取字串格式列印
        System.out.println("id:" + searchHit.getSource().get("id"));
        System.out.println("title:" + searchHit.getSource().get("title"));
        System.out.println("content:" + searchHit.getSource().get("content"));
        System.out.println("-----------------------------------------");
    }

    //釋放資源
    client.close();
}

  

七、查詢結果高亮操作

 1、什麼是高亮顯示

  在進行關鍵字搜尋時,搜尋出的內容中的關鍵字會顯示不同的顏色,稱之為高亮

  百度搜尋關鍵字"傳智播客"

   

  京東商城搜尋"筆記本"

   

 2、高亮顯示的html分析

  透過開發者工具檢視高亮資料的html程式碼實現:

   

  ElasticSearch可以對查詢出的內容中關鍵字部分進行標籤和樣式的設定,但是你需要告訴ElasticSearch使用什麼標籤對高亮關鍵字進行包裹

 3、高亮顯示程式碼實現

@Test
//高亮查詢
public void test11() throws Exception{
    // 建立Client連線物件
    Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

    // 搜尋資料
    SearchRequestBuilder searchRequestBuilder = client
        .prepareSearch("blog2").setTypes("article")
        .setQuery(QueryBuilders.termQuery("title", "搜尋"));

    //設定高亮資料
    HighlightBuilder hiBuilder=new HighlightBuilder();
    hiBuilder.preTags("<font style='color:red'>");
    hiBuilder.postTags("</font>");
    hiBuilder.field("title");
    searchRequestBuilder.highlighter(hiBuilder);

    //獲得查詢結果資料
    SearchResponse searchResponse = searchRequestBuilder.get();

    //獲取查詢結果集
    SearchHits searchHits = searchResponse.getHits();
    System.out.println("共搜到:"+searchHits.getTotalHits()+"條結果!");
    //遍歷結果
    for(SearchHit hit:searchHits){
        System.out.println("String方式列印文件搜尋內容:");
        System.out.println(hit.getSourceAsString());
        System.out.println("Map方式列印高亮內容");
        System.out.println(hit.getHighlightFields());

        System.out.println("遍歷高亮集合,列印高亮片段:");
        Text[] text = hit.getHighlightFields().get("title").getFragments();
        for (Text str : text) {
            System.out.println(str);
        }
    }

    //釋放資源
    client.close();
}

  

相關文章