ElasticSearch 5.3 java Api(增删改)使用

话不多说,环境是ElasticSearch 安装教程 可以看这个。我的环境是5.3 + 分词 。

一、Index的创建

      5.x的默认是不会在你插入数据的时候主动创建index的,所以网上其他地方的介绍代码,都有问题。你是没法直接用的。
创建index:

     // 设置集群名称
    Settings settings = Settings.builder().put("cluster.name", clusterName).build();
    // 创建client
    client = new PreBuiltTransportClient(settings);
    Map<String, Integer> nodeMap = parseNodeIpInfo();
    for (Map.Entry<String, Integer> entry : nodeMap.entrySet()) {
        client.addTransportAddress(
                new InetSocketTransportAddress(InetAddress.getByName(entry.getKey()), entry.getValue()));
    }
    //创建client后,获取index的配置参数
    XContentBuilder mapping = getIndexMapping();
    client.admin().indices().prepareCreate(userIndexName).setSettings(mapping).get();




   /**
     * 解析节点IP信息,多个节点用逗号隔开,IP和端口用冒号隔开
     * @return
     */
    private Map<String, Integer> parseNodeIpInfo() {
        String[] nodeIpInfoArr = esNodes.split(","); //esNodes为外部注入的es的ip
        Map<String, Integer> map = new HashMap<String, Integer>(nodeIpInfoArr.length);
        for (String ipInfo : nodeIpInfoArr) {
            String[] ipInfoArr = ipInfo.split(":");
            map.put(ipInfoArr[0], Integer.parseInt(ipInfoArr[1]));
        }
        return map;
    }

    /**
     * 创建所需的index配置
     * @return
     * @throws IOException
     */
    private XContentBuilder getIndexMapping() throws IOException {
        XContentBuilder mapping = XContentFactory.jsonBuilder();
        mapping.startObject()
               .startObject("index")
                    .startObject("analyzer")
                        .startObject("pinyin_analyzer")
                            .field("tokenizer", "my_pinyin")
                        .endObject()
                        .startObject("default")
                            .field("tokenizer", "ik_max_word")
                        .endObject()
                    .endObject()
                    .startObject("tokenizer")
                        .startObject("my_pinyin")
                            .field("type", "pinyin")
                            // 拼音首字母单独开一个
                            .field("keep_separate_first_letter", true)
                            .field("keep_full_pinyin", true)
                            .field("keep_original", true)
                            .field("limit_first_letter_length", 16)
                            .field("lowercase", true)
                            .field("remove_duplicated_term", true)
                .endObject().endObject().endObject().endObject().endObject();
        return mapping;
    }
// 判断index创建是否成功
IndicesExistsResponse userResponse = client.admin().indices().exists(new IndicesExistsRequest(userIndexName)).actionGet();
 return userResponse.isExists();  //true  存在

二、创建type

      在ElasticSearch里面,上面的index就相当于创建一个了一个数据库,而type则是创建一张表。

    //es里面设置参数的话用这个比较形象的去构建json格式
    XContentBuilder mapping = XContentFactory.jsonBuilder()
                .startObject()
                .startObject(userTypeName) //该type 名
                    .startObject("properties")  
                        .startObject("userId")  //相当于数据库字段名 类型
                            .field("type", "text")  //字段类型
                        .endObject()
                        .startObject("loginName") // 嵌套对象字段
                            .field("type", "keyword") //特殊设置,该字段是拼音分词的
                            .startObject("fields")
                                .startObject("pinyin")
                                    .field("type", "text")
                                    .field("store", false)
                                    .field("term_vector", "with_offsets")
                                    .field("analyzer", "pinyin_analyzer") 
                                    .field("boost", 10)
                                .endObject()
                            .endObject()
                        .endObject() //删去了部分字段
                        .startObject("orgId")
                            .field("type", "text")
                        .endObject()
                        .startObject("orgPath")
                            .field("type", "text")
                        .endObject()
                        .endObject().endObject().endObject();
        PutMappingRequest mappingRequest = Requests.putMappingRequest(userIndexName).type(userTypeName).source(mapping);
        client.admin().indices().putMapping(mappingRequest).actionGet();

//判断type是否存在
TypesExistsRequest type = new TypesExistsRequest(new String[] { userIndexName }, userTypeName);
return client.admin().indices().typesExists(type).actionGet().isExists();

三、增

        向ElasticSearch里面添加数据的话可以一个个插入也可以批量添加:

public void bulkSaveUserToES(List<UserESData> users) throws Exception {

    BulkRequestBuilder bulk = client.prepareBulk();
       //循环添加数据
        for (UserESData u : users) { 
            //这里是用我数据库里面的id作为ElasticSearch的文档id
            bulk.add(client.prepareIndex(userIndexName, userTypeName, u.getUserId()).setSource(JSON.toJSONString(u),XContentType.JSON));
        }
        //执行
        bulk.execute().actionGet();
    }

单个数据保存
public void saveUserESData(final UserESData user) throws Exception {
    client.prepareIndex(userIndexName, userTypeName, user.getUserId())
                    .setSource(JSON.toJSONString(user), XContentType.JSON).get();
}

四、改

        在这里ElasticSearch提供多种方式用于定位要修改的数据:

//根据id修改
XContentBuilder builder = null;
    try {
        builder = XContentFactory.jsonBuilder()
                .startObject()
                    .field("userName", user.getUserName())
                    .field("orgId", user.getOrgId())
                    .field("orgPath", user.getOrgPath())
                .endObject();
    } catch (IOException e) {
        log.error("方法updateUserESData 再构造存储对象时出错!", e);
    }
                                                        //根据这个id
    client.prepareUpdate(userIndexName, userTypeName, user.getUserId()).setDoc(builder)
                    .get();

    //批量根据id更新
    BulkRequestBuilder bulk = client.prepareBulk();
        for (Entry<String, Object[]> info : userInfo.entrySet()) {
            bulk.add(client.prepareUpdate(userIndexName, userTypeName, info.getKey())
                    .setDoc(XContentFactory.jsonBuilder()
                            .startObject()
                                .field("orgId", info.getValue()[0])
                                .field("orgPath", info.getValue()[1])
                                .field("teamId", info.getValue()[2])
                            .endObject()));
                }
    //执行
    bulk.execute().get();    

若是根据某些条件更新,可以使用ElasticSearch的脚本 Painless
对于我们在ElasticSearch里面的每一行数据(文档)都相当于 “ctx“ 数据的属性是可以访问的
ElasticSearch数据图
如上边的图,我点击一行数据可以看到很多属性。我使用ctx._source.userId 就可以获取该userId
在程序里:

//使用ElasticSearch的script来存放脚本 , 让userName修改为newName
Script script = new Script("ctx._source.userName=" + newName);
//创建更新的条件,假如是orgPath要能满足orgInfo[0]这个条件的,就修改userName
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.should(QueryBuilders.matchPhraseQuery("orgPath", orgInfo[0]));
//执行
UpdateByQueryAction.INSTANCE.newRequestBuilder(client).script(script).filter(boolQuery)
                        .source(orgIndexName).get();

//该段代码相当于sql

UPDATE table SET userName = ? WHERE orgPath LIKE ? 

如果条件有多个比如:UPDATE table SET userName = ? WHERE orgPath LIKE ? AND userName LIKE ? 
script 不用变,
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.should(QueryBuilders.matchPhraseQuery("orgPath", orgInfo[0]));
boolQuery.must(QueryBuilders.matchPhraseQuery("userName", "陈"));

//如果希望修改路径(字符串)的部分值,那么参照Painless 的白名单API 可以这样编写脚本
StringBuilder sb = new StringBuilder(); 
sb.append("if(ctx._source.orgPath.startsWith(\"").append(oldOrgPath)
    .append("\")){ctx._source.orgPath=ctx._source.orgPath.replace(\"")
    .append(oldOrgPath).append("\",\"").append(newOrgPath)
    .append("\")}");
Script script = new Script(sb.toString());
/**  如果是以oldOrgPath开头的路径,则替换为newOrgPath  
if(ctx._source.orgPath.startsWith(oldOrgPath)){
    ctx._source.orgPath = ctx._source.orgPath.replace(oldOrgPath,newOrgPath)
}
*/

五、删除

        ElasticSearch的删除

//根据id删除
client.prepareDelete(userIndexName, userTypeName, userId).execute().actionGet();

//根据条件来删除  返回删除条数   queryBuilder  构建的查询条件

long delete = DeleteByQueryAction.INSTANCE.newRequestBuilder(client).filter(queryBuilder).source(userIndexName).get().getDeleted(); 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值