elasticsearch系列-Java客戶端的查詢操作

在上一篇中,我們介紹瞭如何使用Java客戶端對elasticsearch進行索引的創建、mapping信息的設置和文檔的添加,在本篇中我們將主要介紹通過Java客戶端查詢文檔的操作。

使用Java客戶端查詢操作步驟

  • 創建一個client對象
  • 創建一個查詢對象,通過QueryBuilders進行創建,其由很多實現的子類。
  • 使用client執行查詢操作,需提前設置查詢參數
  • 得到查詢返回的結果,默認返回十條數據(如果返回條數過多,可能會導致內存溢出)。通過返回接口可以取查詢結果的記錄數,去查詢結果列表等信息。
  • 關閉client對象。

根據ID查詢文檔

通過前面的學習,我們知道在添加文檔時,elasticsearch會持有一個主鍵即"_id"。在查詢時可以通過這個主鍵進行查詢,示例demo如下所示。

    @Test
    public void queryById() throws UnknownHostException {
        ElasticSearchParams elasticSearchParams = new ElasticSearchParams();
        elasticSearchParams.setIndexName("20200128-xinghaol")
                .setIp("47.107.90.36")
                .setClusterName("my-elasticsearch")
                .setPort(9300);
        SearchResponse searchResponse = ElasticSearchUtil.queryById(elasticSearchParams);
        SearchHits searchHits = searchResponse.getHits();
        System.out.println("總數:" + searchHits.getTotalHits());
        SearchHit[] hits = searchHits.getHits();
        for (int i = 0; i < hits.length; i++) {
            SearchHit searchHit = hits[i];
            System.out.println("查詢結果爲:" + (i + 1) + " " + searchHit.getSourceAsString());
        }
    }

    public static SearchResponse queryById(ElasticSearchParams elasticSearchParams) throws UnknownHostException {
        TransportClient transportClient = buildTransportClient(elasticSearchParams);
        // 需要加判空
        // 查詢id爲1的記錄
        QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1");
        SearchResponse searchResponse = transportClient.prepareSearch(elasticSearchParams.getIndexName())
                .setTypes(elasticSearchParams.getDocumentTypes())
                .setQuery(queryBuilder)
                .get();

        return searchResponse;
    }

    private static TransportClient buildTransportClient(ElasticSearchParams elasticSearchParams) throws UnknownHostException {
        if (Objects.isNull(elasticSearchParams) || Strings.isNullOrEmpty(elasticSearchParams.getIndexName())
                || Strings.isNullOrEmpty(elasticSearchParams.getIp())
                || Objects.isNull(elasticSearchParams.getPort())
                || Strings.isNullOrEmpty(elasticSearchParams.getClusterName())
                || elasticSearchParams.getPort() <= 0) {
            log.error("參數不合法");
            return null;
        }
        // 創建Settings
        Settings settings = Settings.builder()
                .put("cluster.name", elasticSearchParams.getClusterName())
                .put("client.transport.ignore_cluster_name", true)
                .build();

        // 創建transportclient對象
        TransportClient transportClient = new PreBuiltTransportClient(settings);
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName(elasticSearchParams.getIp()), elasticSearchParams.getPort()));

        return transportClient;
    }

在SearchResponse對象中可以得到查詢結果的各種信息,比如文檔總條數、文檔內容等。

根據Term方式查詢

根據Trem方式查詢與根據ID查詢唯一的區別點在於在創建QueryBuilder時爲termQuery(name,value)形式的實現方式,如下所示。

QueryBuilder queryBuilder = QueryBuilders.termQuery(elasticSearchParams.getTermQueryName(), elasticSearchParams.getTermQueryValue());

在得到SearchResponse後,與根據ID查詢的後續操作相同,這裏不再贅述。

根據QueryString查詢

在前面介紹elasticsearch查詢方式時,elasticsearch支持根據字符串的查詢,Java客戶端同樣支持根據字符串的查詢。在創建QueryBuilder時選擇queryStringQuery()的實現方式,可以指定默認的搜索域,若不指定搜索域則在所有的與進行查詢操作,其他操作不在贅述。

查詢elasticsearch分頁設置

在上面的查詢操作中,我們介紹了elasticsearch默認是返回10條查詢數據,但是如果我們想要查詢更多或者分頁查詢操作該怎麼辦?在Java客戶端中transprotClient查詢之前設置起始行號和每頁顯示的條數,示例如下。

 transportClient.prepareSearch(elasticSearchParams.getIndexName())
                    .setTypes(elasticSearchParams.getDocumentTypes())
                    .setFrom(elasticSearchParams.getFrom())
                    .setSize(elasticSearchParams.getSize())
                    .setQuery(queryBuilder);

在查詢結果中高亮顯示

在使用百度、Google等搜索引擎時,查詢出的結果都高亮顯示了我們搜索的關鍵字,在elasticsearch中同樣支持高亮的設置。在查詢時需要指定一個高亮顯示的字段,並且需要指定高亮顯示的前綴和後綴,並將這些設置到client中,查詢得到結果後可以查看高亮顯示的結果。

使用HighlightBuilder設置要高亮的字段名稱,以及要添加的前綴、後綴名稱。在查詢之前設置HighlightBuilder到transportClient中,實例代碼如下所示。

    @Test
    public void queryHighLighter() throws UnknownHostException {
        ElasticSearchParams elasticSearchParams = new ElasticSearchParams();
        elasticSearchParams.setIndexName("20200126-xinghaol")
                .setIp("47.107.90.36")
                .setClusterName("my-elasticsearch")
                .setPort(9300);
        TransportClient transportClient = ElasticSearchUtil.obtainTransport(elasticSearchParams);
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("house_name");
        highlightBuilder.preTags("<em>");
        highlightBuilder.postTags("</em>");

        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("小屋").defaultField("house_name");

        SearchResponse searchResponse = transportClient.prepareSearch().
                setQuery(queryBuilder).
                highlighter(highlightBuilder).get();

        SearchHits searchHits = searchResponse.getHits();
        SearchHit[] hits = searchHits.getHits();
        for (int i = 0; i < hits.length; i++) {
            SearchHit searchHit = hits[i];
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            HighlightField highlightField = highlightFields.get("house_name");
            Text[] fragments = highlightField.getFragments();
            if (fragments != null) {
                System.out.println("當前是第" + i + "個文檔,文檔內容:" + fragments[0].toString());
            }
        }
    }

運行上面demo示例得到如下結果,可以看到分詞後的都已經加上了<em>標籤,即完成了高亮顯示的要求。

當前是第0個文檔,文檔內容:<em>小</em>數點價格房<em>屋</em>01
當前是第1個文檔,文檔內容:龍捲風<em>小屋</em>
當前是第2個文檔,文檔內容:愛的<em>小屋</em>
當前是第3個文檔,文檔內容:這是我修改的房<em>屋</em>名稱
當前是第4個文檔,文檔內容:閃訂房<em>屋</em>20200119

小節

在本篇中我們通過Java客戶端完成了根據ID、關鍵詞、字符串的查詢方式,還介紹了elasticsearch中的分頁設置及高亮顯示的查詢。希望對初學者有所幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章