Springboot整合Elasticsearch,查询数据的方式

参考文档地址:
Elasticsearch 官方文档地址:点击链接
Spring Data Elasticsearch 官方文档地址:点击链接

添加maven依赖

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-data-elasticsearchartifactId>
dependency>

1.初始化Elasticsearch

  • 在yml配置文件中配置es的连接参数(略)
  • 新建一个config类,配置es(如下)
@Configuration
public class ElasticsearchConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        // 这个是springboot的文档推荐写法
//        ClientConfiguration clientConfiguration = ClientConfiguration.builder()
//                .connectedTo("192.168.203.129:9200").build();
//
//        return RestClients.create(clientConfiguration).rest();

        // es官方文档推荐写法
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("192.168.203.129", 9200, "http")));
        return client;
    }
}

2.简单查询

Spring Data Elasticsearch提供了一个ElasticsearchRepository接口,可以很方便的自定义简单的查询方法。

public interface MyRepository extends ElasticsearchRepository<User, Long> {

    /**
     * 根据id或者年龄或者名字查询
     * @param id
     * @param age
     * @param name
     * @return
     */
    User findByIdOrAgeOrName(Long id, Integer age, String name);

    /**
     * 删除年龄大于或等于给定值的数据
     * @param age
     */
    void deleteByAgeGreaterThanEqual(Integer age);

    /**
     * 搜索指定年龄段的user
     * @param start 开始年龄
     * @param end 结束年龄
     * @return
     */
    User findAllByAgeBetween(int start,int end);


}

这里要注意,自定义方法的名字是有规则的,idea会自动提示,根据提示,以及自己想要的操作,书写方法名和对应参数即可。在Spring Data Elasticsearch的文档里也有相关说明
Springboot整合Elasticsearch,查询数据的方式_第1张图片
Springboot整合Elasticsearch,查询数据的方式_第2张图片

1.1测试代码

@Autowired  
private MyRepository myRepository;

// 查询年龄为27岁的用户数据
@Test
void myTest6() {
	User rico = myRepository.findByIdOrAgeOrName(null, 27, null);
	System.out.println(rico);
}

// 插入一条user数据
@Test
void myTest7() throws IOException {
	User user = User.builder()
			.name("rico3")
			.age(35)
			.id(3L)
			.birthday(new Date())
			.build();

	User save = myRepository.save(user);
	System.out.println(save);
	restHighLevelClient.close();
}

// 删除年龄大于或等于29岁的用户的数据
@Test
void myTest8() throws IOException {
	myRepository.deleteByAgeGreaterThanEqual(29);
	restHighLevelClient.close();
}

3.复杂查询

3.1使用ElasticsearchRestTemplate

先看测试代码

@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;

// 使用elasticsearchRestTemplate来查询数据
@Test
void myTest9() {
	// 创建一个query,QueryBuilders下可以选择查询方式
	NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery());
	SearchHits<User> search = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
	for (org.springframework.data.elasticsearch.core.SearchHit<User> userSearchHit : search) {
		User content = userSearchHit.getContent();
		System.out.println(content);
	}
}

@Test
void myTest11() {
	NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
	builder.withQuery(QueryBuilders.matchAllQuery());
	// 搜索age大于27的user数据,这里的写法其实和json查询语句的写法一样的,如下
	/*
	GET /bank/_search
	{
	  "query": {
		"bool": {
		  "must": { "match_all": {} },
		  "filter": {
			"range": {
			  "balance": {
				"gte": 20000,
				"lte": 30000
			  }
			}
		  }
		}
	  }
	}
	 */
	builder.withQuery(QueryBuilders.boolQuery()
			.must(QueryBuilders.matchAllQuery())
			.filter(QueryBuilders.rangeQuery("age").gte(27)));
	NativeSearchQuery query = builder.build();
	SearchHits<User> searchHits = elasticsearchRestTemplate.search(query, User.class);
	for (org.springframework.data.elasticsearch.core.SearchHit<User> searchHit : searchHits) {
		System.out.println(searchHit.getContent());
	}
}

// 查询年龄大于10岁的用户的数量
@Test
public void myTest14() {
	NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
	builder.addAggregation(AggregationBuilders
			.filter("age_gt_10", QueryBuilders.rangeQuery("age").gt(10))
			.subAggregation(AggregationBuilders.count("group_by_count").field("name")));
	NativeSearchQuery searchQuery = builder.build();
	SearchHits<User> search = elasticsearchRestTemplate.search(searchQuery, User.class);
	Filter age_gt_10 = search.getAggregations().get("age_gt_10");
	Aggregations aggregations = age_gt_10.getAggregations();
	ValueCount count = aggregations.get("group_by_count");
	System.out.println(count.getValue());
}

ElasticsearchRestTemplate适合做一些复杂的搜索操作,比如聚合搜索等。需要注意的是,ElasticsearchRestTemplate查询返回的结果需要传入我们的数据实体类User.class

@Data
@Document(indexName = "users") // 将此类标记为Document,索引是users,对应es里的数据
@Builder
public class User {
    @Id
    private Long id;
    @Field(type = FieldType.Keyword)
    private String name;
    @Field(type = FieldType.Long)
    private Integer age;
    @Field(type = FieldType.Date,format= DateFormat.basic_date)
    private Date birthday;
}

还有一个需要注意:在上面的代码myTest14函数中,builder的写法需要基本是和es的json查询语句一样的,如下:
Springboot整合Elasticsearch,查询数据的方式_第3张图片
输出结果是:
Springboot整合Elasticsearch,查询数据的方式_第4张图片

3.2使用RestHighLevelClient

@Autowired  
private RestHighLevelClient restHighLevelClient;

@Test
void myTest() throws IOException {
	// 创建一个索引,并设置了id为1的文档数据
	IndexRequest request = new IndexRequest("spring-data3")
			.id("1")
			.opType(DocWriteRequest.OpType.CREATE)
			.source("name", "rico2")
			.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
	IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
	System.out.println(response.toString());
	restHighLevelClient.close();

// 获取文档内容
@Test
void myTest4() throws IOException {
	GetRequest getRequest = new GetRequest("users", "1");
	boolean exists = restHighLevelClient.indices().exists(new GetIndexRequest(getRequest.index()), RequestOptions.DEFAULT);
	if (exists) {
		GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
		System.out.println(getResponse.getSourceAsString());
	} else {
		System.out.println("索引不存在!");
	}
	restHighLevelClient.close();
}

// 搜索index为users下的所有文档
@Test
void myTest5() throws IOException {
	SearchRequest searchRequest = new SearchRequest("users");
	SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
	searchSourceBuilder.query(QueryBuilders.matchAllQuery());
	searchRequest.source(searchSourceBuilder);
	SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
	SearchHit[] hits = search.getHits().getHits();
	for (SearchHit hit : hits) {
		System.out.println(hit.getSourceAsString());
		System.out.println("=================================");
	}

}

// 查询users下所有用户的年龄平均值
@Test
public void myTest12() throws IOException {
	SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
	AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("average_age").field("age");
	searchSourceBuilder.aggregation(avgAggregationBuilder);

	SearchRequest request = new SearchRequest("users");
	request.source(searchSourceBuilder);

	SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
	Aggregations aggregations = response.getAggregations();
	Avg average_age = aggregations.get("average_age");
	System.out.println(average_age.getValue());
}

// 查询年龄大于10岁的用户的数量,使用restHighLevelClient
@Test
public void myTest13() throws IOException {
	SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
	FilterAggregationBuilder filter = AggregationBuilders
			.filter("age_gt_10", QueryBuilders.rangeQuery("age").gt(10));
	filter.subAggregation(AggregationBuilders.count("group_by_count").field("name"));
	searchSourceBuilder.aggregation(filter);

	SearchRequest request = new SearchRequest("users");
	request.source(searchSourceBuilder);

	SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
	Aggregations aggregations = response.getAggregations();
	Filter age_gt_10 = aggregations.get("age_gt_10");
	Aggregations aggregations1 = age_gt_10.getAggregations();
	ValueCount group_by_count = aggregations1.get("group_by_count");
	System.out.println(group_by_count.getValue());
}

可以看出,RestHighLevelClient既可以做简单的查询,也可以做复杂的查询。如果只需要做简单的数据操作,还是建议用ElasticsearchRepository,代码更简单。和ElasticsearchRestTemplate一样,建立查询条件的代码要参照es的json查询语句的写法,比如这里的myTest13用的就是嵌套查询。

你可能感兴趣的:(ElasticSearch,elasticsearch,spring,boot,java)