本文基于SpringBoot 2.1.1.RELEASE版本配置,搭建的elasticsearch 6.4.3版本(7.1版本和当前的springData版本不兼容),
依赖spring-data-elasticsearh 3.1.3.RELEASE版本

添加依赖

添加maven依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

添加配置参数

#配置es节点信息,逗号分隔,如果没有指定,则启动ClientNode(9200端口是http查询使用的。9300集群使用。这里使用9300.)
spring.data.elasticsearch.clusterNodes:192.168.1.41:9300 
spring.data.elasticsearch.clusterName:spt

使用示例

基于spring-data-elasticsearh操作和使用数据库差不多

1、实体配置

每个实体必须添加@Document注解,必须指定@Id字段

如果属性配置@Field,必须指定type类型

@Document(indexName = "sample-entity", type = "sample", shards = 1, replicas = 0, refreshInterval = "-1")
public class SampleEntity implements Serializable {
	private static final long serialVersionUID = -7400751968589582556L;
	@Id
	private String id;
	@Field(fielddata = true, type = FieldType.Text)
	private String message;
	private String name;
	private String remark;
	private int age;
	//geter seter
}
2、创建Repository接口

Repository接口不需要添加任何注解,只需继承接口(ElasticsearchRepository)即可,在其他地方可以直接@Autowired使用

public interface SampleEntityRepository extends ElasticsearchRepository<SampleEntity, String>{

}
3、操作代码示例

除了自己创建的Repository接口外,还有一个通用的模板类可以直接使用ElasticsearchTemplate

索引操作
@Autowired
private ElasticsearchTemplate template;

public void createIndex() {
	// 创建索引
	template.createIndex(SampleEntity.class);
	// 更新mapping配置
	template.putMapping(SampleEntity.class);
	// 删除索引
	template.deleteIndex(SampleEntity.class);
	// 刷新索引
	template.refresh(SampleEntity.class);
}
保存数据
@Autowired
private SampleEntityRepository repository;

public void addData() {
	for (int i = 1; i <= 15; i++) {

		String documentId = RandomUtils.generateInt(6) + i;
		SampleEntity sampleEntity = new SampleEntity();
		sampleEntity.setId(documentId);
		sampleEntity.setMessage(documentId + "上海");
		sampleEntity.setAge((int) (i * (Math.random() * 100)));
		sampleEntity = repository.save(sampleEntity);
	}
}
查询数据

text类型的字段默认是不允许排序的,如果一定要排序,则需要在对应的实体属性上增加注解 @Field(fielddata = true, type = FieldType.Text)

然后,调用template.putMapping(SampleEntity.class)方法,更新mapping配置后就可以排序了

public void search() {
	// 指定指定排序
	Sort sort = Sort.by(Direction.ASC, "message");
	// 查询所有数据
	Iterable<SampleEntity> list = repository.findAll(sort);
	System.out.println(JsonUtil.obj2Json(list));
	// 条件查询
	QueryBuilder query = QueryBuilders.matchQuery("message", "上海");
	// 指定分页参数
	Pageable page = PageRequest.of(0, 5, sort);
	list = repository.search(query, page);
	System.out.println(JsonUtil.obj2Json(list));
}

在repository上直接指定查询条件

/** between条件 */
List<SampleEntity> findByAgeBetween(int from, int to);

@Query("{\"bool\" : {\"must\" : {\"match\" :{\"message\": \"?0\"}}}}")
//	@Query("{\"term\" : {\"age\" : \"317\"}}")
//	@Query("{\"match\" : {\"message\" : \"?0\"}}")
//	@Query("{\"range\" : {\"age\" : {\"gte\":100} }}")
List<SampleEntity> findList(String msg);

其他查询示例

/**	 分词精确查询	 */
@Test
public void search3() {
	QueryBuilder query = QueryBuilders.termsQuery("age", new int[] { 91, 378 });
	Iterable<SampleEntity> list = repository.search(query);
	System.out.println(JsonUtil.obj2Json(list));
}

/** or 查询 */
@Test
public void search4() {
	// 
	QueryBuilder query1 = QueryBuilders.termsQuery("age", new int[] { 91, 378 });
	QueryBuilder query2 = QueryBuilders.matchQuery("message", "14149910");
	BoolQueryBuilder builder = QueryBuilders.boolQuery().should(query1).should(query2);
	Iterable<SampleEntity> list = repository.search(builder);
	System.out.println(JsonUtil.obj2Json(list));
}
/** and 查询 */
@Test
public void search5() {
	// and 查询
	QueryBuilder query1 = QueryBuilders.termsQuery("age", new int[] { 91, 378 });
	QueryBuilder query2 = QueryBuilders.matchQuery("message", "2958266");
	BoolQueryBuilder builder = QueryBuilders.boolQuery().must(query1).must(query2);
	Iterable<SampleEntity> list = repository.search(builder);
	System.out.println(JsonUtil.obj2Json(list));
}

/** 关键字高亮查询 */
@Test
public void search7() {
	QueryBuilder query2 = QueryBuilders.matchQuery("message", "14149910");

	SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query2)
			.withHighlightFields(new Field("message")).build();

	Page<SampleEntity> list = template.queryForPage(searchQuery, SampleEntity.class, new SearchResultMapper() {

		@Override
		public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
			List<SampleEntity> poems = new ArrayList<>();
			SearchHits hits = response.getHits();
			for (SearchHit searchHit : hits) {
				if (hits.getHits().length <= 0) {
					return null;
				}
				SampleEntity entity = new SampleEntity();
				String highLightMessage = searchHit.getHighlightFields().get("message").fragments()[0].toString();
				entity.setId(searchHit.getId());
				Map<String, Object> map = searchHit.getSourceAsMap();
				entity.setMessage(String.valueOf(map.get("message")));
				entity.setAge(Integer.valueOf(map.get("age").toString()));
				// 反射调用set方法将高亮内容设置进去
				try {
					PropertyUtils.setProperty(entity, "message", highLightMessage);
				} catch (Exception e) {
					e.printStackTrace();
				}
				poems.add(entity);
			}
			if (poems.size() > 0) {
				return new AggregatedPageImpl<T>((List<T>) poems);
			}

			return null;
		}
	});
	System.out.println(JsonUtil.obj2Json(list));
}
/** 范围 查询 */
@Test
public void search8() {
	QueryBuilder query1 = QueryBuilders.rangeQuery("age").gt(20).lt(50);
	Iterable<SampleEntity> list = repository.search(query1);
	System.out.println(JsonUtil.obj2Json(list));
	list = repository.findByAgeBetween(10, 20);
	System.out.println(JsonUtil.obj2Json(list));
}

参考

更多推荐