ElasticSearch 5.3java Api(增删改)使用

xiaoxiao2021-02-28  40

话不多说,环境是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“ 数据的属性是可以访问的 如上边的图,我点击一行数据可以看到很多属性。我使用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();
转载请注明原文地址: https://www.6miu.com/read-2250310.html

最新回复(0)