4, java操作es

操作es的方式

  • TransportClient Elasticsearch

不推荐, es8.0之后将废弃 transport-client.html

  • REST Client
  • SpringDataEs

REST Client

es提供了2中java rest client版本。点击打开官方文档

  • java low level rest client

低级别的rest客户端,通过http与集群交互,用户需自己编组请求JSON串,及解析响应JSON串。兼容所有Elasticsearch版本。就是在kibana上的所有命令都可以使用。

  • java high rest client

高级别的REST客户端,基于低级别的REST客户端,使用的版本需要保存和ES服务一致的版本,否则会有版本问题。

java low level rest client

入门小案例

  • maven依赖
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>6.8.14</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>
  • 查询具体id的books
// 构建httpclientBuilder, 设置es节点数据
RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost("127.0.0.1", 9200));
RestClient restClient = restClientBuilder.build();
// 构建Request对象  相当于在kibana中运行 GET /books/_doc/P1Ux7XcBNThmh3q1jaOf?pretty=true
org.elasticsearch.client.Request esRequest = new org.elasticsearch.client.Request("GET", "/books/_doc/P1Ux7XcBNThmh3q1jaOf");
esRequest.addParameter("pretty", "true");
org.elasticsearch.client.Response esResponse = restClient.performRequest(esRequest);
HttpEntity entity = esResponse.getEntity();
String s = EntityUtils.toString(entity);
System.out.println(s);

所以低级client功能强大, 可以完成所有的功能需求, 缺点:需要构建请求, 效率不高

java high rest client

入门

  • 依赖
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>6.8.14</version>
</dependency>
  • 查询具体id的books
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200)));
GetRequest getRequest = new GetRequest("books", "_doc", "P1Ux7XcBNThmh3q1jaOf");
GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
Map<String, Object> source = response.getSource();
source.entrySet().forEach(entry->{
	System.out.println(entry.getKey() + " : " + entry.getValue());
});

SpringDataEs

版本对应关系

image-20210303173022192

ORM

使用springdataEs 对象映射, 可以通过orm直接查询

  • 依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.2.13.RELEASE</version>
        <relativePath/> 
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
         <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 配置文件
spring:
  elasticsearch:
    rest:
      uris: http://172.19.16.229:9200
      username:
      password:
  • books

Field的type自定义好, 如果用auto的话, 会出现意想不到的问题, 尤其是keyword 不会分词, text会分词

@Document: 文档对应注解, indexName索引名称

@Data
@Document(indexName = "books", type = "_doc")
@NoArgsConstructor
@AllArgsConstructor
public class Books {

    @Id
    private String bookid;

    @Field(value = "title",type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String title;

    @Field(value = "author", type = FieldType.Keyword)
    private String author;

    @Field(value = "price", type = FieldType.Float)
    private double price;

    @Field(value = "time", type = FieldType.Date, pattern = "yyyy-MM-dd HH:mm:ss", format = DateFormat.custom)
    private String time;

}

注意: 如果 private String time; 写成 private Date time; 会报错。

  • BookRepository

编写一个

package top.itkaoti.es.repository;

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;
import top.itkaoti.es.domain.Books;

@Component
public interface BookRepository  extends ElasticsearchRepository<Books, String>{

}

  • ApplicationTest
    
@SpringBootTest
public class ApplicationTest {

    @Autowired
    private BookRepository bookRepository;

    @Test
    public void test(){
        LocalDateTime now = LocalDateTime.now();
        String format = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        bookRepository.save(new Books("P1Ux7XcBNThmh3q1jaOf", "python开发指南", "小逗比", 9.9,
                format));

        Optional<Books> byId = bookRepository.findById("P1Ux7XcBNThmh3q1jaOf");
        System.out.println(byId.get());
    }
}

ElasticsearchRestTemplate

@SpringBootTest
public class ApplicationTest {

    
    @Autowired
    private ElasticsearchRestTemplate template;


    @Test
    public void test1(){
        GetQuery getQuery = new GetQuery();
        getQuery.setId("P1Ux7XcBNThmh3q1jaOf");
        Books books = template.queryForObject(getQuery, Books.class);
        System.out.println(books);

    }

}

项目地址gitee