赞
踩
Java REST提供了两种风格的客户端连接工具,Java High Level REST Client、Java Low Level REST Client,这里我就不去细说Java Low Level REST Client了,因为这我确实没用到过,也不是很了解,我说一下Java High Level REST Client。
首先如果你喜欢看官方文档的话,我把地址粘贴在这里,官网讲的也比较详细:Java High Level REST Client | Java REST Client [7.4] | Elastic
第一步添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency><!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.0</version>
</dependency><!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.4.0</version>
</dependency><dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.4.0</version>
</dependency><dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.69</version>
</dependency>
第二步:
在配置文件添加对应的地址以及端口:
elasticsearch:
host: 127.0.0.1
port: 9200
第三步使用:
- @Autowired
- private RestHighLevelClient client; //注入client、后面的代码会省略
-
- @Test
- public void addIndexAndmapping() throws IOException {
- IndicesClient indices = client.indices();
- //创建索引
- CreateIndexRequest createIndexRequest = new CreateIndexRequest("test_index");
- //设置分片数量以及副本数量
- createIndexRequest.settings(Settings.builder()
- .put("index.number_of_shards", 3)
- .put("index.number_of_replicas", 2)
- );
- //添加映射,相当于给表创建字段
- String mapping ="{properties={address={analyzer=ik_max_word, type=text}, name={type=keyword}, age={type=integer}}}";
- System.out.println(mapping);
- createIndexRequest.mapping(mapping, XContentType.JSON);
- CreateIndexResponse response = indices.create(createIndexRequest, RequestOptions.DEFAULT);//创建索引
- System.out.println(response.isAcknowledged());
- }
- @Test
- public void queryIndex() throws IOException {
- IndicesClient indices = client.indices();
- GetIndexRequest getIndexRequest = new GetIndexRequest("person");
- GetIndexResponse getIndexResponse = indices.get(getIndexRequest, RequestOptions.DEFAULT);
- Map<String, MappingMetaData> mappings = getIndexResponse.getMappings();
- mappings.forEach((k,v)->{
- System.out.println("key:"+k+",v:"+v.getSourceAsMap());
- });
- }
- @Test
- public void addDoc() throws IOException {
- //数据对象
- Person p = new Person();
- p.setName("meiting");
- p.setAddress("sichuan");
- p.setAge(22);
- IndexRequest request = new IndexRequest("person").id("1").source(JSON.toJSONString(p),XContentType.JSON);
- IndexResponse index = client.index(request, RequestOptions.DEFAULT);
- }
就跟添加文档一样,在es中如果指定文档的id存在就会就会更新这个文档。操作方式跟上面添加文档一样,不过需要指定文档的id。
5.1根据id查询文档或者删除文档
- @Test
- public void findDocByID() throws IOException {
- GetRequest getIndexRequest = new GetRequest("person","1");
- GetResponse documentFields = client.get(getIndexRequest, RequestOptions.DEFAULT);
- System.out.println(documentFields.getSourceAsString());
- }
- //根据id删除文档
- @Test
- public void delDocByID() throws IOException {
- DeleteRequest deleteRequest = new DeleteRequest("person","1");
- DeleteResponse documentFields = client.delete(deleteRequest, RequestOptions.DEFAULT);
- System.out.println(documentFields.getId());
- }
5.2查询所有文档
- @Test
- public void findAllDoc() throws IOException {
- SearchRequest sr = new SearchRequest("person");
-
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
- sourceBuilder.from(0).size(20);//指定分页
- MatchAllQueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
- sourceBuilder.query(queryBuilder);
- sr.source(sourceBuilder);
- SearchResponse search = client.search(sr, RequestOptions.DEFAULT);
- System.out.println(search.getHits().getTotalHits()); //查询到的所有的文档数量
- SearchHits hits = search.getHits();
- hits.forEach(ele->{
- System.out.println(ele.getSourceAsString());
- });
- }
5.3term查询(词条查询) text支持分词,keyword不支持分词
- @Test
- public void termQuery() throws IOException {
- SearchRequest requst = new SearchRequest("person");
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
-
- QueryBuilder queryBuilder = QueryBuilders.termQuery("name","阿");
- sourceBuilder.query(queryBuilder);
-
- requst.source(sourceBuilder);
- SearchResponse search = client.search(requst, RequestOptions.DEFAULT);
-
- SearchHit[] hits = search.getHits().getHits();
- for (SearchHit hit : hits) {
- System.out.println(hit.getSourceAsString());
- }
- }
- /** 类似于
- get person/_search
- {
- "query":{
- "term":{
- "name":{
- "value":"阿"
- }
- }
- }
- }
- */
5.4match查询
- @Test
- public void matchQuery() throws IOException {
- SearchRequest requst = new SearchRequest("person");
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
- MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "老板");
- queryBuilder.operator(Operator.AND);//求并集
- sourceBuilder.query(queryBuilder);
- requst.source(sourceBuilder);
- SearchResponse search = client.search(requst, RequestOptions.DEFAULT);
- SearchHit[] hits = search.getHits().getHits();
- for (SearchHit hit : hits) {
- System.out.println(hit.getSourceAsString());
- }
- }
- /**类似于
- get person/_search
- {
- "query":{
- "match": {
- "name": {
- "query":"永恩",
- "operator": "and"
- }
- }
- }
- }
- */
5.5模糊查询
wildcard查询:会对查询条件进行分词。还可以使用通配符 ?(任意单个字符) *(0个或者多个字符)
regexp查询:正则查询
prefix查询:前缀查询
- @Test
- public void wildSearch() throws IOException {
- SearchRequest requst = new SearchRequest("person");
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
-
- QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("name","菲*");
- //QueryBuilder queryBuilder = QueryBuilders.regexpQuery("name","菲*"); //正则查询
- //QueryBuilder queryBuilder = QueryBuilders.prefixQuery("name","菲"); //前缀查询
- sourceBuilder.query(queryBuilder);
- requst.source(sourceBuilder);
- SearchResponse search = client.search(requst, RequestOptions.DEFAULT);
- SearchHit[] hits = search.getHits().getHits();
- for (SearchHit hit : hits) {
- System.out.println(hit.getSourceAsString());
- }
- }
5.6范围查询
range范围查询:查找指定字段在指定范围内包含值。查询年龄20到26的人并排序
- @Test
- public void rangeQuery() throws IOException {
- SearchRequest requst = new SearchRequest("person");
-
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
- QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").gte(20).lte(26);
- sourceBuilder.query(queryBuilder);
- sourceBuilder.sort("age", SortOrder.DESC); //排序
- requst.source(sourceBuilder);
- SearchResponse search = client.search(requst, RequestOptions.DEFAULT);
- SearchHit[] hits = search.getHits().getHits();
- for (SearchHit hit : hits) {
- System.out.println(hit.getSourceAsString());
- }
- }
- /**类似于
- get person/_search
- {
- "query":{
- "range": {
- "age": {
- "gte": 20,
- "lte": 24
- }
- }
- },
- "sort":[ //排序
- {
- "age":{
- "order":"desc"
- }
- }
- ]
- }
- */
5.7querySt ring查询
queryString查询就是:对查询条件进行分词,然后将分词后的查询条件和词条进行等值匹配。然后取并集。
这种查询的特点就是可以指定多个字段查询。比如下面就是查名字和地址中包含“老”的数据。
- @Test
- public void queryStringQuery() throws IOException {
- SearchRequest requst = new SearchRequest("person");
-
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
-
- QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("老").field("name").field("address").defaultOperator(Operator.OR);
- sourceBuilder.query(queryBuilder);
- sourceBuilder.sort("age", SortOrder.DESC); //排序
- requst.source(sourceBuilder);
- SearchResponse search = client.search(requst, RequestOptions.DEFAULT);
- SearchHit[] hits = search.getHits().getHits();
- for (SearchHit hit : hits) {
- System.out.println(hit.getSourceAsString());
- }
- }
- /**类似于
- get person/_search
- {
- "query":{
- "query_string": {
- "fields": ["name","address"],
- "query": "永恩 OR 瑟提"
- }
- }
- }
- */
除了上面说的这些常用的查询操作外还包括许多其他的查询,比如说聚合查询、高亮查询等等。在官网都可以查到对应的例子。到时候可以去官网看对应的例子。
Spring Data也提供了操作ES数据库的功能,因为我们现在的项目基本都是基于Spring的,所以集成这个功能之后很多项目在考虑选择的时候也会把这种方式考了进来,我之前参与的项目就是采用的这种方式来操作ES数据库的。
添加依赖:添加依赖的时候要注意版本的选择,要选择对应的版本,参考官网Spring Data Elasticsearch - Reference Documentation
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springDataEs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>springDataEs</name>
<description>Demo project for Spring Boot</description>
<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.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
然后第二步配置文件
spring.elasticsearch.rest.uris=127.0.0.1:9200
前面要做的步骤就这两步。
2.1创建实体以及接口
- @Document(indexName = "animal",createIndex = true,shards = 1,replicas = 1)
- @Data
- public class Animal {
- @Id
- private long id;
-
- @Field(type= FieldType.Text)
- private String name;
-
- @Field(type=FieldType.Text)
- private String address;
-
- @Field(type = FieldType.Integer)
- private int age;
- }
这上面需要注意的就是几个注解:
@Document 注解作用在类上,说明这是一个文档对象。
indexName:索引名称
createIndex:是否需要创建索引,若为true就会自动创建索引
shards、replicas:分片数量和副本数量
@Field(type= FieldType.Text)
在es对应的这个字段的数据类型,这里FieldType.Tex在es创建后这个字段就对应为text类型的。
2.2创建存储库接口
创建了这个接口并继承ElasticsearchRepository之后,就可以使用了。
- public interface AnimalRepostory extends ElasticsearchRepository<Animal,Long> {
- }
继承关系:
然后就可以基本的使用了,步骤非常简单。。。
2.3新增文档
我新写了一个接口,去尝试添加一个文档。
- @PostMapping("addDoc")
- public void addDoc(){
- Animal animal = new Animal();
- animal.setId(1);
- animal.setName("tew");
- animal.setAddress("111");
- animal.setAge(12);
- animalRepostory.save(animal);
- }
效果
可以看到,我们添加文档成功了,这个索引也自动给我们创建了。
Spring Data ElasticSearch对ES的操作进行了很完美的包装,他是基于Java High Level REST Client写的,使用起来非常方便。这里我就不对其他的方法进行讲解了,它的crud自己去搭建个环境跑起来,只要环境搭好之后后面就很方便了。对于简单的查询我们可以直接创建对应的接口方法就可以了。下面给出官网给出的例子:
- interface PersonRepository extends Repository<Person, Long> {
-
- List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
-
- // Enables the distinct flag for the query
- List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
- List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
-
- // Enabling ignoring case for an individual property
- List<Person> findByLastnameIgnoreCase(String lastname);
- // Enabling ignoring case for all suitable properties
- List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
-
- // Enabling static ORDER BY for a query
- List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
- List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
- }
分页查询和排序,只需要在定义接口方法的时候给出Pageable以及Sort规则就可以了。
例子:
- @PostMapping("findPage")
- public void findPage(){
- Pageable page = Pageable.ofSize(3).withPage(1);
- Iterable<Animal> all = animalRepostory.findAll(page);
- for(Iterator<Animal> iterator = all.iterator(); iterator.hasNext();System.out.println(iterator.next())){
- }
- }
-
- @PostMapping("findPageSort")
- public void findPageSort(){
- Sort sort = Sort.by("age").descending();
- Iterable<Animal> all = animalRepostory.findAll(sort);
- for(Iterator<Animal> iterator = all.iterator(); iterator.hasNext();System.out.println(iterator.next())){
- }
- }
自定义DSL查询:
这里用一个模糊查询举例:
在对应的接口创建一个接口,并在@Query注解里面写上对应的查询语句
- public interface AnimalRepostory extends ElasticsearchRepository<Animal,Long> {
- @Query("{\n" +
- " \"wildcard\": {\n" +
- " \"name\": {\n" +
- " \"value\": \"t*\"\n" +
- " }\n" +
- " }\n" +
- " }")
- List<Animal> findTest();
- }
效果:
- @PostMapping("findQuery")
- public void findQuery(){
- List<Animal> test = animalRepostory.findTest();
- test.forEach(ele->{
- System.out.println(ele);
- });
- }
Spring Data还提供了很多其他的查询功能,如果有需要用到的我建议可以去看看官网。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。