ElasticSearch(六)之java api基本用法

 

1. Client 
說明:Client是Elasticsearch所有API的主入口,主要方法有: 

AdminClient admin() 獲取ES管理客戶端
GetRequestBuilder prepareGet() 準備一個GET請求
IndexRequestBuilder prepareIndex(String index, String type) 準備一個新增文檔的請求
DeleteRequestBuilder prepareDelete() 準備一個刪除文檔的請求
BulkRequestBuilder prepareBulk() 準備一個批量操作的請求
SearchRequestBuilder prepareSearch(String... indices) 準備一個查詢請求
UpdateRequestBuilder prepareUpdate() 準備一個更新的請求(更新的本質是先查詢索引替換更新的值後進行替換,所以反而比插入更耗性能)


AdminClient 
說明:對ES進行管理的客戶端,主要方法有: 

ClusterAdminClient cluster() 產生一個允許從集羣中執行action或操作的client
IndicesAdminClient indices() 產生一個允許從索引中執行action或操作的client



IndicesAdminClient 
說明:對ES的index進行管理的客戶端,主要方法有: 

IndicesExistsRequestBuilder prepareExists(String... indices) 準備一個判斷索引是否存在的請求
TypesExistsRequestBuilder prepareTypesExists(String... index) 準備一個判斷類型是否存在的請求
CreateIndexRequestBuilder prepareCreate(String index) 準備一個創建索引的請求
DeleteIndexRequestBuilder prepareDelete(String... indices) 準備一個刪除索引的請求
AnalyzeRequestBuilder prepareAnalyze(@Nullable String index, String text) 準備一個對字符串進行分詞的請求
PutIndexTemplateRequestBuilder preparePutTemplate(String name) 準備一個設置模板的請求
DeleteIndexTemplateRequestBuilder prepareDeleteTemplate(String name) 準備一個刪除模板的請求
UpdateSettingsRequestBuilder prepareUpdateSettings(String... indices) 準備一個更新設置的請求,如更新副本數量等
PutMappingRequestBuilder preparePutMapping(String... indices) 準備一個新建映射關係的請求


QueryBuilders 
說明:爲prepareSearch組裝查詢參數,如: 

Java代碼 

  1. client.prepareSearch(esIndex).setTypes(esType).setQuery(QueryBuilders.matchQuery("global_ana_ch", "杭州西湖")).setFrom(0).setSize(1).get();  
matchAllQuery() 構造匹配所有文檔的查詢
matchQuery(String name, Object text) 構造查詢一個被分析器分析過的字段的查詢(match查詢)
matchPhraseQuery(String name, Object text) 它和matchQuery的區別是它不會對傳入的參數(text)進行分詞,而是以其做爲一個完整的詞進行查詢(類似百度查詢時加引號的功能)如“有限公司”會分詞成“有限”和“公司”,根據分詞規則,“有限企業”、“大公司”這樣的數據也會被查詢出來,使用此方法後則必須包含“有限公司”纔會被查詢出
matchPhrasePrefixQuery(String name, Object text) 中文查詢時matchPhraseQuery和matchPhrasePrefixQuery並沒有什麼區別,英文查詢時matchPhrasePrefixQuery會以短語形式查詢,查詢時關鍵字不會被分詞,而是直接以一個字符串的形式查詢
commonTermsQuery(String name, Object text) 對query進行重寫,區分低頻詞和高頻詞,並根據Elasticsearch傳遞的highFreqOccur和lowFreqOccur將高頻詞和低頻詞構造成BooleanQuery它的好處是減少了對高頻詞(如and)查詢的性能影響,增加的查詢效率
termQuery(String name, Object value) 多字段查詢
termsQuery(String name, Object... values) 和termQuery類似,多個term組合
fuzzyQuery(String name, Object value) 模糊查詢(like)
prefixQuery(String name, String prefix) 前綴匹配查詢
rangeQuery(String name) 範圍區間查詢
wildcardQuery(String name, String query) 使用通配符查詢(*,?)
regexpQuery(String name, String regexp) 正則查詢org.apache.lucene.util.automaton.RegExp
queryStringQuery(String queryString) 字符串查詢
boolQuery() 布爾型判斷的查詢must::多個查詢條件的完全匹配,相當於 andmustNot::多個查詢條件的相反匹配,相當於 notshould::至少有一個查詢條件匹配, 相當於 or
SpanQuery SpanQuery是按照詞在文章中的距離或者查詢幾個相鄰詞的查詢。
spanFirstQuery 接受另一個跨度查詢的匹配必須出現在第N的位置
spanNearQuery 接受多個跨度查詢的匹配必須在指定的距離,並可能在相同的順序
spanNotQuery 包裝另一個跨度查詢,排除了任何文檔匹配查詢
spanOrQuery 結合多個跨度查詢,返回文檔的匹配任何指定的查詢
spanWithinQuery 和spanContainingQuery類似
spanContainingQuery 這個查詢內部會有多個子查詢,但是會設定某個子查詢優先級更高,作用更大,通過關鍵字little和big來指定
spanMultiTermQueryBuilder 包裝了 term, range, prefix, wildcard, regexp,或 fuzzy查詢
spanTermQuery

和spanQuery類似,同時可以做爲spanQuery的子句        

初始化elasticsearch客戶端

   Settings settings = Settings.builder() 
                .put("cluster.name", "my-application")// 集羣名稱yml配置
                .put("client.transport.ping_timeout", "60s")// 超時時間
                .put("client.transport.sniff", false)//是否開啓自動發現,非局域網關閉
                .put("client.transport.ignore_cluster_name", false).build();
        try {
            client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(InetAddress.getByName(ip), 9300));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

elasticsearch常使用的用法

package com.xue;

 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import org.apache.commons.io.FileUtils;
 import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder;
 import org.elasticsearch.action.get.GetResponse;
 import org.elasticsearch.action.search.SearchRequestBuilder;
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.client.Client;
import org.elasticsearch.client.IndicesAdminClient;
 import org.elasticsearch.index.query.BoolQueryBuilder;
 import org.elasticsearch.index.query.MatchQueryBuilder;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.search.aggregations.AggregationBuilders;
 import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
 import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
 import org.elasticsearch.search.sort.SortOrder;
 import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
 import java.util.Map;

/**
 * Created by xuehan on 2018/12/10.
 */
/**1. index的操作*/
 public class ElSearch {
    private Client client = null;
    @Before
    public void init(){
        ESTest esTest = new ESTest();
        client = esTest.getClient();
    }
    /**2. mapping映射操作*/
     @Test
    public void testCreateIndex() {
        IndicesAdminClient indices = client.admin().indices();
        String esIndex = "myindex";
        // 判斷inedx是否存在
        IndicesExistsResponse indicesExistsResponse = indices.prepareExists(esIndex).get();
        if (indicesExistsResponse.isExists()) {
            // 存在時先刪除index
            indices.prepareDelete(esIndex).get();
        }
        // 創建前校驗(index不存在)
        indicesExistsResponse = indices.prepareExists(esIndex).get();
        Assert.assertFalse(indicesExistsResponse.isExists());
        // 開始創建index
        indices.prepareCreate(esIndex).get();
        // 創建後校驗(index存在)
        indicesExistsResponse = indices.prepareExists(esIndex).get();
        Assert.assertTrue(indicesExistsResponse.isExists());
    }
    @Test
    public void testMapping() throws IOException {
        String esIndex = "testMapping";
        IndicesAdminClient indices = client.admin().indices();
        // 判斷inedx是否存在
        IndicesExistsResponse indicesExistsResponse = indices.prepareExists(esIndex).get();
        if (indicesExistsResponse.isExists()) {
            // 存在時先刪除index
            indices.prepareDelete(esIndex).get();
        }
        // 創建新的index
        indices.prepareCreate(esIndex).get();
        // 執行前判斷(mapping不存在)
        String esType = "esType";
        GetMappingsResponse getMappingsResponse = indices.prepareGetMappings(esIndex).setTypes(esType).get();
        Assert.assertTrue(getMappingsResponse.mappings().isEmpty());
        // 執行mapping
        PutMappingRequestBuilder builder = indices.preparePutMapping(esIndex).setType(esType);
        String mappingFile = getClass().getResource("/").getPath() + "search/lg_line_mapping.json";
        String mappingSource = FileUtils.readFileToString(new File(mappingFile));
        builder.setSource(mappingSource).get();
        // 執行後判斷(mapping存在)
        getMappingsResponse = indices.prepareGetMappings(esIndex).setTypes(esType).get();
        Assert.assertFalse(getMappingsResponse.mappings().isEmpty());
    }
    @Test
    public void testIndexing() {
        String esType = "esType";
        String esIndex = "myindex";
        // 不管有沒有,先刪除數據
        client.prepareDelete(esIndex, esType, "1").execute();

        // 執行前判斷(數據不存在)
        GetResponse response = client.prepareGet(esIndex, esType, "1").get();
        Assert.assertNull(response.getSourceAsString());

        // 插入數據
        LineIndexingVO lineIndexingVO = new LineIndexingVO();
        lineIndexingVO.setId(1L);
        lineIndexingVO.setLineNo("LM2017041913250001");
        lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
        String lineIndexingVOStr = JSONObject.toJSONString(lineIndexingVO);
        Map<String, Object> map = JSONObject.parseObject(lineIndexingVOStr, Map.class);
        client.prepareIndex(esIndex, esType, "1").setSource(map).execute();

        // 執行後判斷(數據存在)
        response = client.prepareGet(esIndex, esType, "1").get();
        Assert.assertNotNull(response.getSourceAsString());
    }
    /**4. matchQuery查詢**/
    /**
     * 關鍵詞匹配,global_ana_ch是一個分詞的字段可以進行搜索匹配
     */
    @Test
    public void testMatchQuery() {
        String esType = "esType";
        String esIndex = "myindex";
         // 插入數據
        LineIndexingVO lineIndexingVO = new LineIndexingVO();
        lineIndexingVO.setId(1L);
        lineIndexingVO.setLineNo("LM2017041913250001");
        lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
        String lineIndexingVOStr = JSONObject.toJSONString(lineIndexingVO);
        Map<String, Object> map = JSONObject.parseObject(lineIndexingVOStr, Map.class);
        client.prepareIndex(esIndex, esType, "1").setSource(map).execute();

        // 執行matchQuery查詢
        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(esIndex).setTypes(esType);
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("global_ana_ch", "杭州西湖");
        SearchResponse response = searchRequestBuilder.setQuery(matchQuery).setFrom(0).setSize(1).get();
        Assert.assertEquals(1, response.getHits().getTotalHits());
    }
    /**
     * 過濾查詢
     */
    @Test
    public void testTerm() {
        String esType = "esType";
        String esIndex = "myindex";
        // 插入數據
        LineIndexingVO lineIndexingVO = new LineIndexingVO();
        lineIndexingVO.setId(1L);
        lineIndexingVO.setLineNo("LM2017041913250001");
        lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
        String lineIndexingVOStr = JSONObject.toJSONString(lineIndexingVO);
        Map<String, Object> map = JSONObject.parseObject(lineIndexingVOStr, Map.class);
        client.prepareIndex(esIndex, esType, "1").setSource(map).execute();

        // 執行term查詢,相當於select * from lg_line where id=1 and lineNo="LM2017041913250001"
        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(esIndex).setTypes(esType);
         BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("lineNo", "LM2017041913250001"));
       // boolQueryBuilder.must(QueryBuilders.termQuery("id", 1));
        SearchResponse response = searchRequestBuilder.setQuery(boolQueryBuilder).get();
        Assert.assertEquals(1, response.getHits().getTotalHits());

        // 執行term查詢,相當於select * from lg_line where id=1 and lineNo="LM2017041913250001" and lineNo!="LM2017041913250001"
        boolQueryBuilder.mustNot(QueryBuilders.termQuery("lineNo", "LM2017041913250001"));
        response = searchRequestBuilder.setQuery(boolQueryBuilder).setFrom(0).setSize(1).get();
        Assert.assertEquals(0, response.getHits().getTotalHits());
    }
    /**
     * 排序測試
     */
    @Test
    public void testOrder() {
        String esType = "esType";
        String esIndex = "myindex";
         // 插入數據
        LineIndexingVO lineIndexingVO = new LineIndexingVO();
        lineIndexingVO.setId(1L);
        lineIndexingVO.setLineNo("LM2017041913250001");
        lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
        String lineIndexingVOStr = JSONObject.toJSONString(lineIndexingVO);
        Map<String, Object> map = JSONObject.parseObject(lineIndexingVOStr, Map.class);

        client.prepareIndex(esIndex, esType, "1").setSource(map).execute();
        // 第二條數據比第一條少了“杭州”
        lineIndexingVO = new LineIndexingVO();
        lineIndexingVO.setId(2L);
        lineIndexingVO.setLineNo("LM2017041913250002");
        lineIndexingVO.setGlobal_ana_ch("浙江,冬瓜,西瓜,地鐵,番茄泡");
        String lineIndexingVOStr1 = JSONObject.toJSONString(lineIndexingVO);
        Map<String, Object> map1 = JSONObject.parseObject(lineIndexingVOStr1, Map.class);

        client.prepareIndex(esIndex, esType, "2").setSource(map1).execute();

        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("global_ana_ch", "浙江杭州");
        // 根據匹配度倒序排列,匹配度高的排在前面
        SearchResponse response = client.prepareSearch(esIndex).setTypes(esType).setQuery(matchQuery).setFrom(0).setSize(2)
                .addSort("_score", SortOrder.DESC).get();
        Assert.assertEquals("1", response.getHits().iterator().next().getId());
        // 根據匹配度順序排列,匹配度低的排在前面
        response = client.prepareSearch(esIndex).setTypes(esType).setQuery(matchQuery).setFrom(0).setSize(2).addSort("_score", SortOrder.ASC).get();
        Assert.assertEquals("2", response.getHits().iterator().next().getId());
    }
    /**7.統計查詢**/
     @Test
    public void testAggs() {
        String esType = "esType1";
        String esIndex = "aggs";
         // 插入數據
        LineIndexingVO lineIndexingVO = new LineIndexingVO();
        lineIndexingVO.setId(1L);
        lineIndexingVO.setLineType("1");
        lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
        String lineIndexingVOStr1 = JSONObject.toJSONString(lineIndexingVO);
        Map<String, Object> map1 = JSONObject.parseObject(lineIndexingVOStr1, Map.class);
        client.prepareIndex(esIndex, esType, "1").setSource(map1).execute();

        lineIndexingVO = new LineIndexingVO();
        lineIndexingVO.setId(2L);
        lineIndexingVO.setLineType("1");
        lineIndexingVO.setGlobal_ana_ch("浙江,冬瓜,西瓜,地鐵,番茄泡");
        String lineIndexingVOStr2 = JSONObject.toJSONString(lineIndexingVO);
        Map<String, Object> map2 = JSONObject.parseObject(lineIndexingVOStr2, Map.class);
        client.prepareIndex(esIndex, esType, "2").setSource(map2).execute();

        lineIndexingVO = new LineIndexingVO();
        lineIndexingVO.setId(3L);
        lineIndexingVO.setLineType("2");
        lineIndexingVO.setGlobal_ana_ch("浙江,冬瓜,西瓜,地鐵,番茄泡");
        String lineIndexingVOStr3 = JSONObject.toJSONString(lineIndexingVO);
        Map<String, Object> map3 = JSONObject.parseObject(lineIndexingVOStr3, Map.class);
        client.prepareIndex(esIndex, esType, "3").setSource(map3).execute();

         /**
          * 需要設置索引
          * {
          "properties": {
          "lineType": {
          "type":     "text",
          "fielddata": true
          }
          }
          }
          http://47.105.74.94:9200/aggs/_mapping/esType1
          */
        // 根據lineType進行分類統計,type=1的有2條,type=2的有1條
        TermsAggregationBuilder termsBuilder = AggregationBuilders.terms("by_lineType").field("lineType");
        SearchResponse response = client.prepareSearch(esIndex).setTypes(esType).addAggregation(termsBuilder).setSize(10).get();
        StringTerms aggregation = response.getAggregations().get("by_lineType");
        Assert.assertEquals(2, aggregation.getBucketByKey("1").getDocCount());
        Assert.assertEquals(1, aggregation.getBucketByKey("2").getDocCount());
    }
    class LineIndexingVO{
         private double id;
        private String lineNo;
        private String lineType;
        private String global_ana_ch;

        public double getId() {
            return id;
        }

        public void setId(double id) {
            this.id = id;
        }

        public String getLineNo() {
            return lineNo;
        }

        public void setLineNo(String lineNo) {
            this.lineNo = lineNo;
        }

        public String getGlobal_ana_ch() {
            return global_ana_ch;
        }

        public void setGlobal_ana_ch(String global_ana_ch) {
            this.global_ana_ch = global_ana_ch;
        }

        public String getLineType() {
            return lineType;
        }

        public void setLineType(String lineType) {
            this.lineType = lineType;
        }
    }
}

 

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