Elasticsearch-索引的批量操作

索引的批量操作

  • 批量查询和批量增删改

    • 批量查询
#批量查询
GET product/_search
GET /_mget
{
   
   
  "docs": [
    {
   
   
      "_index": "product",
      "_id": 2
    },
    {
   
   
      "_index": "product",
      "_id": 3
    }
  ]
}

GET product/_mget
{
   
   
  "docs": [
    {
   
   
      "_id": 2
    },
    {
   
   
      "_id": 3
    }
  ]
}
#SELECT * FROM TABLE WHERE id in()
GET product/_mget
{
   
   
  "ids": [
    2,
    3,
    4
  ]
}

GET product/_mget
{
   
   
  "docs": [
    {
   
   
      "_id": 2,
      "_source": 
<think> 我们被要求使用elasticsearch-rest-client(低级别客户端)来实现批量插入对象,而不使用high-level-client。根据引用[3],我们知道high-level-client已经被弃用,所以使用低级别客户端是合理的。 步骤: 1. 创建RestClient实例。 2. 构建批量请求的JSON体。批量操作的格式要求每个操作有两行:一行是操作和元数据,一行是源文档(对于索引操作)。 3. 发送HTTP请求到_bulk端点。 注意:批量操作的格式如下: { "index" : { "_index" : "test", "_id" : "1" } } { "field1" : "value1" } { "index" : { "_index" : "test", "_id" : "2" } } { "field1" : "value2" } 我们将对象列表转换为这种格式的JSON字符串,然后通过HttpEntity封装,使用RestClient发送请求。 代码示例: 假设我们有一个对象列表,每个对象是一个Map或者是一个可以转换为JSON的对象。 我们将使用Jackson库来转换对象为JSON字符串,但也可以使用其他JSON库。 首先,添加依赖(如果还没有): implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.5' 然后,编写批量插入的方法: </think> 以下是使用**elasticsearch-rest-client**(低级客户端)实现对象批量插入的完整方案,无需依赖高级客户端(high-level-client): ### 一、核心实现步骤 #### 1. 添加依赖(Gradle) ```gradle implementation 'org.elasticsearch.client:elasticsearch-rest-client:7.17.0' // 与ES版本一致 implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0' // JSON序列化 ``` #### 2. 构建批量请求体 ```java import org.apache.http.entity.ContentType; import org.apache.http.nio.entity.NStringEntity; import org.elasticsearch.client.Request; import org.elasticsearch.client.RestClient; // 对象转换为JSON工具 private String toJson(Object obj) throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(obj); } // 构建批量请求 public Request buildBulkRequest(List<Object> objects, String indexName) { StringBuilder bulkBody = new StringBuilder(); for (Object obj : objects) { // 操作元数据 bulkBody.append(String.format( "{ \"index\" : { \"_index\" : \"%s\" } }%n", // %n保证换行符 indexName )); // 文档主体 bulkBody.append(toJson(obj)).append("\n"); // 必须换行 } Request request = new Request("POST", "/_bulk"); request.setEntity(new NStringEntity(bulkBody.toString(), ContentType.APPLICATION_JSON)); return request; } ``` #### 3. 执行批量插入 ```java public void bulkInsert(RestClient restClient, List<Object> objects, String indexName) { try { Request request = buildBulkRequest(objects, indexName); Response response = restClient.performRequest(request); // 解析响应(示例) String responseBody = EntityUtils.toString(response.getEntity()); System.out.println("Bulk response: " + responseBody); } catch (IOException e) { throw new RuntimeException("Bulk insert failed", e); } } ``` ### 二、关键注意事项 1. **批量格式规范**: - 每行必须用`\n`分隔,不可省略 - 操作类型支持`index`(创建/更新)、`create`(仅创建)、`delete`等 ```json { "index": { "_index":"users", "_id":"1" } } { "name":"Alice", "age":28 } ``` 2. **性能优化**: ```java // 在RestClientBuilder中配置 RestClient.builder(new HttpHost("localhost", 9200)) .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder .setMaxConnTotal(100) // 最大连接数 .setMaxConnPerRoute(50) // 单路由最大连接 ); ``` 3. **错误处理**: ```java // 解析ES返回的错误信息 JsonNode root = new ObjectMapper().readTree(responseBody); if (root.get("errors").asBoolean()) { for (JsonNode item : root.get("items")) { JsonNode error = item.get("index").get("error"); if (error != null) { System.err.println("Error: " + error.get("reason")); } } } ``` ### 三、完整调用示例 ```java // 1. 初始化客户端 RestClient restClient = RestClient.builder( new HttpHost("localhost", 9200) ).build(); // 2. 准备数据 List<User> users = Arrays.asList( new User("Alice", 28), new User("Bob", 32) ); // 3. 执行批量插入 bulkInsert(restClient, users, "users"); // 4. 关闭客户端 restClient.close(); ``` ### 四、与高级客户端对比 | **特性** | **低级客户端** | **高级客户端** | |----------------|-----------------------------------|-----------------------------------| | 依赖项 | 仅需`rest-client` | 需`rest-high-level-client` | | 代码量 | 需手动构建JSON请求体 | 封装好的API(如`BulkRequest`) | | 灵活性 | 完全控制请求/响应格式 | 受限于预定义模型 | | 维护性 | 需处理底层细节 | 更易读和维护 | | 版本兼容性 | 兼容更广泛的ES版本 | 需严格匹配ES服务端版本 | > 建议:需要精细控制请求或轻量化部署时使用低级客户端;追求开发效率时推荐高级客户端[^3]。 ### 五、常见问题解决 1. **413 Request Too Large**: ```java // 分批处理(每批500条) int batchSize = 500; for (int i = 0; i < objects.size(); i += batchSize) { List<Object> batch = objects.subList(i, Math.min(i + batchSize, objects.size())); bulkInsert(restClient, batch, indexName); } ``` 2. **序列化特殊字段**: ```java // Jackson配置处理LocalDateTime ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); ``` ### 附录:User对象示例 ```java public class User { private String name; private int age; // 必须有无参构造函数 public User() {} public User(String name, int age) { this.name = name; this.age = age; } // getters/setters省略 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值