分享

ElasticSearch Java API 之 索引管理【 版本2.4.1】

问题导读


1.ElasticSearch如何实现管理索引的?
2.IndicesAdminClient定义了几种prepareXXX()方法作为创建请求的入口点?
3.类型存在API的作用是什么?
4.如何创建复杂索引?
5.如何关闭打开索引?
6.如何创建索引的别名?







ElasticSearch为了便于处理索引管理(Indices administration)请求,提供了
org.elasticsearch.client.IndicesAdminClient接口。通过如下代码从 Client 对象中获得这个接口的实现:

[mw_shl_code=bash,true]IndicesAdminClient indicesAdminClient = client.admin().indices();
[/mw_shl_code]


IndicesAdminClient定义了好几种prepareXXX()方法作为创建请求的入口点。
1. 索引存在API
索引存在API用于检查集群中是否存在由prepareExists调用指定的索引。
[mw_shl_code=bash,true] /**
* 判断索引是否存在
* @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();*/
}[/mw_shl_code]

prepareExists()可以同时指定多个索引:
[mw_shl_code=bash,true]IndicesExistsResponse response = indicesAdminClient.prepareExists(index1, index2 ....).get();
[/mw_shl_code]

2. 类型存在API
类型存在API和索引存在API类似,只是不是用来检查索引是否存在,而是检查指定索引下的指定类型是否存在。为了确保成功返回结果,请确保索引已经存在,否则不会查找到指定的类型。下面代码演示查找索引下的指定类型:
[mw_shl_code=bash,true] /**
* 判断类型是否存在
* @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();
}

[/mw_shl_code]


3. 创建索引API

创建索引API可以用来建立一个新索引。我们可以创建空索引或者给它设置它的映射(mapping)和设置信息(settings)。

3.1 创建空索引

下面代码创建了一个空索引:
[mw_shl_code=bash,true] /**
* 创建空索引 默认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();
}[/mw_shl_code]

查看索引状态信息:
[mw_shl_code=bash,true]{
"state": "open",
"settings": {
"index": {
"creation_date": "1476078197394",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "rBATEkx_SBq_oUEIlW8ryQ",
"version": {
"created": "2030399"
}
}
},
"mappings": {

},
"aliases": [

]
}[/mw_shl_code]

3.2. 创建复杂索引

下面代码创建复杂索引,给它设置它的映射(mapping)和设置信息(settings),指定分片个数为3,副本个数为2,同时设置school字段不分词。
[mw_shl_code=bash,true]/**
* 创建索引 指定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();
}[/mw_shl_code]

查看索引状态信息:
[mw_shl_code=bash,true]{
"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": [

]
}[/mw_shl_code]


4. 删除索引

删除索引API允许我们反向删除一个或者多个索引。
[mw_shl_code=bash,true]/**
     * 删除索引
     * @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();
    }[/mw_shl_code]

5. 关闭索引
关闭索引API允许我们关闭不使用的索引,进而释放节点和集群的资源,如cpu时钟周期和内存。
[mw_shl_code=bash,true] /**
     * 关闭索引
     * @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();
    }[/mw_shl_code]

测试:
[mw_shl_code=bash,true] @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);
    }[/mw_shl_code]


关闭之前:
1.png
关闭之后:
2.png
file:///tmp/WizNote/7be1616a-4ffe-4109-8f5c-0ac55899308d/index_files/944042984.png
6. 打开索引
打开索引API允许我们打开我们之前使用关闭索引API
[mw_shl_code=bash,true] /**
     * 关闭索引
     * @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();
    }[/mw_shl_code]

7. 设置映射API

设置映射API允许我们在指定索引上一次性创建或修改一到多个索引的映射。如果设置映射必须确保指定的索引必须存在,否则会报错。
[mw_shl_code=bash,true]/**
     * 设置映射
     * @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();
    }[/mw_shl_code]

先创建一个空索引,这样该索引上不会有映射,再使用下面代码添加映射:
[mw_shl_code=bash,true] @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);
    }[/mw_shl_code]

添加映射之后的索引信息:
[mw_shl_code=bash,true]{
    "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": [
        
    ]
}[/mw_shl_code]

8. 别名API

别名API允许我们可以为已经存在的索引创建别名
[mw_shl_code=bash,true]/**
     * 为索引创建别名
     * @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();
    }[/mw_shl_code]

测试:下面代码为simple-index索引创建一个别名为simple:
[mw_shl_code=bash,true]  @Test
    public void addAliasIndex() throws Exception {
        String index = "simple-index";
        String aliasName = "simple";
        boolean result = IndexAPI.addAliasIndex(client, index, aliasName);
        logger.info("--------- addAliasIndex {}", result);
    }[/mw_shl_code]

结果图:
file:///tmp/WizNote/143035012.png 3.png

9.  别名存在API
别名存在API允许我们检查是否存在至少一个我们列举出的的别名,注意是判断的索引别名,不是索引。我们可以在别名中使用星号通配符。
[mw_shl_code=bash,true] /**
     * 判断别名是否存在
     * @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();
    }[/mw_shl_code]

测试,下面代码检查以sim开头的索引别名和test索引别名是否存在,我们列举的索引别名只要有一个存在就会返回true。
[mw_shl_code=bash,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
    }[/mw_shl_code]

10. 获取别名API

获取别名API可以列举出当前已经定义的的别名

[mw_shl_code=bash,true]/**
     * 获取别名
     * @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());
            }
        }
    }[/mw_shl_code]
测试,下面代码展示以sim开头的别名和test别名:
[mw_shl_code=bash,true]@Test
    public void getAliasIndex() throws Exception {
        String aliasName = "simp*";
        String aliasName2 = "test";
        IndexAPI.getAliasIndex(client, aliasName, aliasName2); // simple test
    }

[/mw_shl_code]


11. 删除别名API

删除别名API允许我们删除指定索引的别名,如果索引没有该别名,则会报错

[mw_shl_code=bash,true]  /**
     * 删除别名
     * @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();
    }[/mw_shl_code]

测试,下面代码删除test-index索引的别名test:
[mw_shl_code=bash,true] @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
    }[/mw_shl_code]


12. 更新设置API

更新设置API允许我们更新特定索引或全部索引的设置。


[mw_shl_code=bash,true]/**
     * 更新设置
     * @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();
    }[/mw_shl_code]

测试,下面代码更改副本数为2,修改分片个数会报错:
[mw_shl_code=bash,true] @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
    }[/mw_shl_code]


13. 索引统计API
索引统计API可以提供关于索引,文档,存储以及操作的信息,如获取,查询,索引等。这些信息按类别进行了划分,如果需要输出特定信息需要在请求时指定。下面代码演示了获取指定索引的全部信息:

[mw_shl_code=bash,true]/**
     * 索引统计
     * @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());
    }[/mw_shl_code]



完成代码与测试代码地址:

已有(1)人评论

跳转到指定楼层
xingoo 发表于 2016-10-18 08:57:00
我们以前也封装过java的api,不过,在应用中推荐还是使用rest api,因为升级的时候影响能小一点。
现在Logstash默认的es-output也是http模式的,而不是Transport Client模式的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条