天天看點

[ElasticSearch2.x]Java API 之 索引管理

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/SunnyYoona/article/details/52791465

ElasticSearch為了便于處理索引管理(Indices administration)請求,提供了

org.elasticsearch.client.IndicesAdminClient接口。通過如下代碼從 Client 對象中獲得這個接口的實作:

IndicesAdminClient indicesAdminClient = client.admin().indices(); IndicesAdminClient定義了好幾種prepareXXX()方法作為建立請求的入口點。

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#1-%E5%88%A4%E6%96%AD%E7%B4%A2%E5%BC%95%E5%AD%98%E5%9C%A8 1. 判斷索引存在

索引存在API用于檢查叢集中是否存在由prepareExists調用指定的索引。

/**
 * 判斷索引是否存在
 * @param client
 * @param index
 * @return
 */
public static boolean isIndexExists(Client client, String index) {
    if(Objects.equal(client, null)){
        logger.info("--------- IndexAPI isIndexExists 請求用戶端為null");
        return false;
    }
    if(StringUtils.isBlank(index)){
        logger.info("--------- IndexAPI isIndexExists 索引名稱為空");
        return false;
    }
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    IndicesExistsResponse response = indicesAdminClient.prepareExists(index).get();
    return response.isExists();
    /* 另一種方式
    IndicesExistsRequest indicesExistsRequest = new IndicesExistsRequest(index);
    IndicesExistsResponse response = client.admin().indices().exists(indicesExistsRequest).actionGet();*/
}           

prepareExists()可以同時指定多個索引:

IndicesExistsResponse response = indicesAdminClient.prepareExists(index1, index2 ....).get();           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#2-%E5%88%A4%E6%96%AD%E7%B1%BB%E5%9E%8B%E5%AD%98%E5%9C%A8 2. 判斷類型存在

類型存在API和索引存在API類似,隻是不是用來檢查索引是否存在,而是檢查指定索引下的指定類型是否存在。為了確定成功傳回結果,請確定索引已經存在,否則不會查找到指定的類型。下面代碼示範查找索引下的指定類型:

/**
 * 判斷類型是否存在
 * @param client
 * @param index
 * @param type
 * @return
 */
public static boolean isTypeExists(Client client, String index, String type) {
    if(!isIndexExists(client, index)){
        logger.info("--------- isTypeExists 索引 [{}] 不存在",index);
        return false;
    }
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    TypesExistsResponse response = indicesAdminClient.prepareTypesExists(index).setTypes(type).get();
    return response.isExists();
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#3-%E5%88%9B%E5%BB%BA%E7%B4%A2%E5%BC%95api 3. 建立索引API

建立索引API可以用來建立一個新索引。我們可以建立空索引或者給它設定它的映射(mapping)和設定資訊(settings)。

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#31-%E5%88%9B%E5%BB%BA%E7%A9%BA%E7%B4%A2%E5%BC%95 3.1 建立空索引

下面代碼建立了一個空索引:

/**
 * 建立空索引  預設setting 無mapping
 * @param client
 * @param index
 * @return
 */
public static boolean createSimpleIndex(Client client, String index){
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    CreateIndexResponse response = indicesAdminClient.prepareCreate(index).get();
    return response.isAcknowledged();
}           

檢視索引狀态資訊:

{
    "state": "open",
    "settings": {
        "index": {
            "creation_date": "1476078197394",
            "number_of_shards": "5",
            "number_of_replicas": "1",
            "uuid": "rBATEkx_SBq_oUEIlW8ryQ",
            "version": {
                "created": "2030399"
            }
        }
    },
    "mappings": {
        
    },
    "aliases": [
        
    ]
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#32-%E5%88%9B%E5%BB%BA%E5%A4%8D%E6%9D%82%E7%B4%A2%E5%BC%95 3.2. 建立複雜索引

下面代碼建立複雜索引,給它設定它的映射(mapping)和設定資訊(settings),指定分片個數為3,副本個數為2,同時設定school字段不分詞。

/**
 * 建立索引 指定setting
 * @param client
 * @param index
 * @return
 */
public static boolean createIndex(Client client, String index){
    // settings
    Settings settings = Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 2).build();
    // mapping
    XContentBuilder mappingBuilder;
    try {
        mappingBuilder = XContentFactory.jsonBuilder()
                .startObject()
                    .startObject(index)
                        .startObject("properties")
                            .startObject("name").field("type", "string").field("store", "yes").endObject()
                            .startObject("sex").field("type", "string").field("store", "yes").endObject()
                            .startObject("college").field("type", "string").field("store", "yes").endObject()
                            .startObject("age").field("type", "integer").field("store", "yes").endObject()
                            .startObject("school").field("type", "string").field("store", "yes").field("index", "not_analyzed").endObject()
                        .endObject()
                    .endObject()
                .endObject();
    } catch (Exception e) {
        logger.error("--------- createIndex 建立 mapping 失敗:",e);
        return false;
    }
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    CreateIndexResponse response = indicesAdminClient.prepareCreate(index)
            .setSettings(settings)
            .addMapping(index, mappingBuilder)
            .get();
    return response.isAcknowledged();
}           
{
    "state": "open",
    "settings": {
        "index": {
            "creation_date": "1476078400025",
            "number_of_shards": "3",
            "number_of_replicas": "2",
            "uuid": "ToakRDisSYyX7vjH30HR-g",
            "version": {
                "created": "2030399"
            }
        }
    },
    "mappings": {
        "simple-index": {
            "properties": {
                "college": {
                    "store": true,
                    "type": "string"
                },
                "school": {
                    "index": "not_analyzed",
                    "store": true,
                    "type": "string"
                },
                "sex": {
                    "store": true,
                    "type": "string"
                },
                "name": {
                    "store": true,
                    "type": "string"
                },
                "age": {
                    "store": true,
                    "type": "integer"
                }
            }
        }
    },
    "aliases": [
        
    ]
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#4-%E5%88%A0%E9%99%A4%E7%B4%A2%E5%BC%95 4. 删除索引

删除索引API允許我們反向删除一個或者多個索引。

/**
 * 删除索引
 * @param client
 * @param index
 */
public static boolean deleteIndex(Client client, String index) {
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    DeleteIndexResponse response = indicesAdminClient.prepareDelete(index).execute().actionGet();
    return response.isAcknowledged();
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#5-%E5%85%B3%E9%97%AD%E7%B4%A2%E5%BC%95 5. 關閉索引

關閉索引API允許我們關閉不使用的索引,進而釋放節點和叢集的資源,如cpu時鐘周期和記憶體。

/**
 * 關閉索引
 * @param client
 * @param index
 * @return
 */
public static boolean closeIndex(Client client, String index){
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    CloseIndexResponse response = indicesAdminClient.prepareClose(index).get();
    return response.isAcknowledged();
}           

測試:

@Test
public void closeIndex() throws Exception {
    String index = "suggestion-index";
    if(!IndexAPI.isIndexExists(client, index)){
        logger.info("--------- closeIndex 索引 [{}] 不存在", index);
        return;
    }
    boolean result = IndexAPI.closeIndex(client, index);
    logger.info("--------- closeIndex {}",result);
}           

關閉之前:

關閉之後:

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#6-%E6%89%93%E5%BC%80%E7%B4%A2%E5%BC%95 6. 打開索引

打開索引API允許我們打開我們之前使用關閉索引API

/**
 * 關閉索引
 * @param client
 * @param index
 * @return
 */
public static boolean openIndex(Client client, String index){
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    OpenIndexResponse response = indicesAdminClient.prepareOpen(index).get();
    return response.isAcknowledged();
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#7-%E8%AE%BE%E7%BD%AE%E6%98%A0%E5%B0%84api 7. 設定映射API

設定映射API允許我們在指定索引上一次性建立或修改一到多個索引的映射。如果設定映射必須確定指定的索引必須存在,否則會報錯。

/**
 * 設定映射
 * @param client
 * @param index
 * @param type
 * @return
 */
public static boolean putIndexMapping(Client client, String index, String type){
    // mapping
    XContentBuilder mappingBuilder;
    try {
        mappingBuilder = XContentFactory.jsonBuilder()
                .startObject()
                    .startObject(type)
                        .startObject("properties")
                            .startObject("name").field("type", "string").field("store", "yes").endObject()
                            .startObject("sex").field("type", "string").field("store", "yes").endObject()
                            .startObject("college").field("type", "string").field("store", "yes").endObject()
                            .startObject("age").field("type", "long").field("store", "yes").endObject()
                            .startObject("school").field("type", "string").field("store", "yes").field("index", "not_analyzed").endObject()
                        .endObject()
                    .endObject()
                .endObject();
    } catch (Exception e) {
        logger.error("--------- createIndex 建立 mapping 失敗:", e);
        return false;
    }
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    PutMappingResponse response = indicesAdminClient.preparePutMapping(index).setType(type).setSource(mappingBuilder).get();
    return response.isAcknowledged();
}           

先建立一個空索引,這樣該索引上不會有映射,再使用下面代碼添加映射:

@Test
public void putIndexMapping() throws Exception {
    String index = "simple-index";
    String type = "simple-type";
    if(!IndexAPI.isIndexExists(client, index)){
        logger.info("--------- putIndexMapping 索引 [{}] 不存在", index);
        return;
    }
    boolean result = IndexAPI.putIndexMapping(client, index, type);
    logger.info("--------- putIndexMapping {}",result);
}           

添加映射之後的索引資訊:

{
    "state": "open",
    "settings": {
        "index": {
            "creation_date": "1476108496237",
            "number_of_shards": "5",
            "number_of_replicas": "1",
            "uuid": "9SR5OQJ-QLSARFjmimvs1A",
            "version": {
                "created": "2030399"
            }
        }
    },
    "mappings": {
        "simple-type": {
            "properties": {
                "college": {
                    "store": true,
                    "type": "string"
                },
                "school": {
                    "index": "not_analyzed",
                    "store": true,
                    "type": "string"
                },
                "sex": {
                    "store": true,
                    "type": "string"
                },
                "name": {
                    "store": true,
                    "type": "string"
                },
                "age": {
                    "store": true,
                    "type": "long"
                }
            }
        }
    },
    "aliases": [
        
    ]
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#8-%E5%88%AB%E5%90%8Dapi 8. 别名API

别名API允許我們可以為已經存在的索引建立别名

/**
 * 為索引建立别名
 * @param client
 * @param index
 * @param alias
 * @return
 */
public static boolean addAliasIndex(Client client, String index , String alias){
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    IndicesAliasesResponse response = indicesAdminClient.prepareAliases().addAlias(index, alias).get();
    return response.isAcknowledged();
}           

測試:下面代碼為simple-index索引建立一個别名為simple:

@Test
public void addAliasIndex() throws Exception {
    String index = "simple-index";
    String aliasName = "simple";
    boolean result = IndexAPI.addAliasIndex(client, index, aliasName);
    logger.info("--------- addAliasIndex {}", result);
}           

結果圖:

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#9-%E5%88%AB%E5%90%8D%E5%AD%98%E5%9C%A8api 9. 别名存在API

别名存在API允許我們檢查是否存在至少一個我們列舉出的的别名,注意是判斷的索引别名,不是索引。我們可以在别名中使用星号通配符。

/**
 * 判斷别名是否存在
 * @param client
 * @param aliases
 * @return
 */
public static boolean isAliasExist(Client client, String... aliases){
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    AliasesExistResponse response = indicesAdminClient.prepareAliasesExist(aliases).get();
    return response.isExists();
}           

測試,下面代碼檢查以sim開頭的索引别名和test索引别名是否存在,我們列舉的索引别名隻要有一個存在就會傳回true。

@Test
public void isAliasExist() throws Exception {
    String aliasName = "simp*";
    String aliasName2 = "test";
    boolean result = IndexAPI.isAliasExist(client, aliasName, aliasName2);
    logger.info("--------- isAliasExist {}", result); // true
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#10-%E8%8E%B7%E5%8F%96%E5%88%AB%E5%90%8Dapi 10. 擷取别名API

擷取别名API可以列舉出目前已經定義的的别名

/**
 * 擷取别名
 * @param client
 * @param aliases
 */
public static void getAliasIndex(Client client, String... aliases){
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    GetAliasesResponse response = indicesAdminClient.prepareGetAliases(aliases).get();
    ImmutableOpenMap<String, List<AliasMetaData>> aliasesMap = response.getAliases();
    UnmodifiableIterator<String> iterator = aliasesMap.keysIt();
    while(iterator.hasNext()){
        String key = iterator.next();
        List<AliasMetaData> aliasMetaDataList = aliasesMap.get(key);
        for(AliasMetaData aliasMetaData : aliasMetaDataList){
            logger.info("--------- getAliasIndex {}", aliasMetaData.getAlias());
        }
    }
}           

測試,下面代碼展示以sim開頭的别名和test别名:

@Test
public void getAliasIndex() throws Exception {
    String aliasName = "simp*";
    String aliasName2 = "test";
    IndexAPI.getAliasIndex(client, aliasName, aliasName2); // simple test
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#11-%E5%88%A0%E9%99%A4%E5%88%AB%E5%90%8Dapi 11. 删除别名API

删除别名API允許我們删除指定索引的别名,如果索引沒有該别名,則會報錯

/**
 * 删除别名
 * @param client
 * @param index
 * @param aliases
 * @return
 */
public static boolean deleteAliasIndex(Client client, String index, String... aliases){
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    IndicesAliasesResponse response = indicesAdminClient.prepareAliases().removeAlias(index, aliases).get();
    return response.isAcknowledged();
}           

測試,下面代碼删除test-index索引的别名test:

@Test
public void deleteAliasIndex() throws Exception {
    String index = "test-index";
    String aliasName = "test";
    boolean result = IndexAPI.deleteAliasIndex(client, index, aliasName);
    logger.info("--------- deleteAliasIndex {}", result); // true
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#12-%E6%9B%B4%E6%96%B0%E8%AE%BE%E7%BD%AEapi 12. 更新設定API

更新設定API允許我們更新特定索引或全部索引的設定。

/**
 * 更新設定
 * @param client
 * @param index
 * @param settings
 * @return
 */
public static boolean updateSettingsIndex(Client client, String index, Settings settings){
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    UpdateSettingsResponse response = indicesAdminClient.prepareUpdateSettings(index).setSettings(settings).get();
    return response.isAcknowledged();
}           

測試,下面代碼更改副本數為2,修改分片個數會報錯:

@Test
public void updateSettingsIndex() throws Exception {
    String index = "test-index";
    Settings settings = Settings.builder().put("index.number_of_replicas", 2).build();
    if(!IndexAPI.isIndexExists(client, index)){
        logger.info("--------- updateSettingsIndex 索引 [{}] 不存在", index);
        return;
    }
    boolean result = IndexAPI.updateSettingsIndex(client, index, settings);
    logger.info("--------- updateSettingsIndex {}", result); // true
}           

https://note.youdao.com/md/?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB38171b60196c13bd751063ce82c779af%3Fmethod%3Ddownload%26read%3Dtrue#13-%E7%B4%A2%E5%BC%95%E7%BB%9F%E8%AE%A1api 13. 索引統計API

索引統計API可以提供關于索引,文檔,存儲以及操作的資訊,如擷取,查詢,索引等。這些資訊按類别進行了劃分,如果需要輸出特定資訊需要在請求時指定。下面代碼示範了擷取指定索引的全部資訊:

/**
 * 索引統計
 * @param client
 * @param index
 */
public static void indexStats(Client client, String index) {
    IndicesAdminClient indicesAdminClient = client.admin().indices();
    IndicesStatsResponse response = indicesAdminClient.prepareStats(index).all().get();
    ShardStats[] shardStatsArray = response.getShards();
    for(ShardStats shardStats : shardStatsArray){
        logger.info("shardStats {}",shardStats.toString());
    }
    Map<String, IndexStats> indexStatsMap = response.getIndices();
    for(String key : indexStatsMap.keySet()){
        logger.info("indexStats {}", indexStatsMap.get(key));
    }
    CommonStats commonStats = response.getTotal();
    logger.info("total commonStats {}",commonStats.toString());
    commonStats = response.getPrimaries();
    logger.info("primaries commonStats {}", commonStats.toString());
}           

完成代碼與示範位址:

https://github.com/sjf0115/OpenDiary/blob/master/ElasticSearchDemo/src/main/java/com/sjf/open/api/IndexAPI.java https://github.com/sjf0115/OpenDiary/blob/master/ElasticSearchDemo/src/test/java/com/sjf/open/api/IndexAPITest.java