Maven 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
ElasticsearchRepository<T, ID>
Spring 提供的便捷操作 Dao 层接口,通过继承此接口可以实现简单的增删改查操作。
T:
与索引结构对应的 Model。
ID:
索引里的 ID。
- Dao 样例
@Repository
public interface GoodsSpuEsDao extends ElasticsearchRepository<GoodsSpuEs, Long> {
List<GoodsSpuEs> findByTitleAndShopId(String title, Long shopId);
}
- Model 样例
/** 创建索引使用,默认项目启动时自动创建索引 */
@Document(indexName = "goods_spu", createIndex = false)
/** 设置分片和副本 */
@Setting(shards = 3, replicas = 1)
public class GoodsSpuEs {
/** 必须有 ID,这里的 ID 是全局唯一的标识,等同于 es 中的 "_id" */
@Id
@Field(name = "id", type = FieldType.Long)
private Long id;
/** 店铺 ID */
@Field(name = "shop_id", type = FieldType.Long)
private Long shopId;
/** 商品分类 ID */
@Field(name = "category_id", type = FieldType.Long)
private Long categoryId;
/** 商品店铺分类 ID */
@Field(name = "shop_category_id", type = FieldType.Long)
private Long shopCategoryId;
/** 商品名称 */
@Field(name = "title", type = FieldType.Text, analyzer = "ik_max_word")
private String title;
/** 商品的售价;此处价格应填写 SKU 的最低价格 */
@Field(name = "price", type = FieldType.Double)
private BigDecimal price;
@Field(name = "main_image", type = FieldType.Keyword)
private String mainImage;
@Field(name = "sales", type = FieldType.Integer)
private Integer sales;
@Field(name = "base_activity", type = FieldType.Integer)
private Integer baseActivity;
@Field(name = "if_wholesale", type = FieldType.Boolean)
private Boolean ifWholesale;
@Field(name = "if_ziti", type = FieldType.Boolean)
private Boolean ifZiti;
@Field(name = "if_express", type = FieldType.Boolean)
private Boolean ifExpress;
@Field(name = "tag", type = FieldType.Text, analyzer = "ik_max_word")
private String tag;
/** 地理位置;格式:纬度,经度 */
@Field(name = "location")
@GeoPointField
private String location;
}
这样一个基本的 Dao 就可以使用了,如下:
也可以以 find
开头的规范自己组合一些查询条件,如下:
还可以使用注解方式字节写一些 DSL,如下:
ElasticsearchRestTemplate
- 更新
public void updateGoodsSpu(GoodsSpuEs goodsSpuEsIn) throws IllegalAccessException {
log.info("【更新商品信息到 ES】- 入参:${}$", goodsSpuEsIn);
// 索引
IndexCoordinates indexCoordinates = IndexCoordinates.of(goodsSpuEsIn.findIndexName());
// 更新信息
Document document = Document.create();
document.putAll(goodsSpuEsIn.objectToMap());
// 构建更新对象
UpdateQuery updateQuery = UpdateQuery.builder(String.valueOf(goodsSpuEsIn.getId()))
.withDocument(document)
.build();
// 增量更新
restTemplate.update(updateQuery, indexCoordinates);
}
- 商品名称搜索
public List<GoodsSpuEsOut> queryByNearby(GoodsSpuSearch goodsSpuSearch) {
log.info("【综合化查询商品列表】- 入参:${}$", goodsSpuSearch);
// 先构建基础查询条件对象
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// 商品名称搜索条件构建
if (StringUtils.isNotBlank(goodsSpuSearch.getTitle())) {
boolQueryBuilder.must(QueryBuilders.matchQuery("title", goodsSpuSearch.getTitle()));
}
// 排序
SortBuilder sortBuilder = SortBuilders.fieldSort("sales").order(SortOrder.DESC);
// 分页条件
PageRequest pageRequest = PageRequest.of(goodsSpuSearch.getPage(), goodsSpuSearch.getSize());
// 组装条件
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
.withPageable(pageRequest)
.withSort(sortBuilder)
.build();
SearchHits<GoodsSpuEsOut> searchHits = restTemplate.search(nativeSearchQuery, GoodsSpuEsOut.class);
log.info("【综合化查询商品列表】- 查询结果:${}$", searchHits);
// 获取到商品结果集
List<GoodsSpuEsOut> goodsSpuEsOutList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
return goodsSpuEsOutList;
}
- 地理位置搜索
public List<GoodsSpuEsOut> queryByNearby(GoodsSpuSearch goodsSpuSearch) {
log.info("【综合化查询商品列表】- 入参:${}$", goodsSpuSearch);
// 先构建基础查询条件对象
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// 商品名称搜索条件构建
if (StringUtils.isNotBlank(goodsSpuSearch.getTitle())) {
boolQueryBuilder.must(QueryBuilders.matchQuery("title", goodsSpuSearch.getTitle()));
}
// 2. 地理位置
if (StringUtils.isNotBlank(goodsSpuSearch.getLocation())) {
// 处理经纬度
String[] split = goodsSpuSearch.getLocation().split(",");
String lot = Double.valueOf(split[0]);
String lat = Double.valueOf(split[1]);
boolQueryBuilder.filter(
QueryBuilders.geoDistanceQuery("location")
// 3. 商品范围
.distance(goodsSpuSearch.getDistance().doubleValue(), DistanceUnit.KILOMETERS)
.point(lat, lot)
);
}
// 排序
// 距离排
SortBuilder sortBuilder = SortBuilders.fieldSort("price").order(SortOrder.ASC);
// 分页条件
PageRequest pageRequest = PageRequest.of(goodsSpuSearch.getPage(), goodsSpuSearch.getSize());
// 组装条件
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
.withPageable(pageRequest)
.withSort(sortBuilder)
.build();
SearchHits<GoodsSpuEsOut> searchHits = restTemplate.search(nativeSearchQuery, GoodsSpuEsOut.class);
log.info("【综合化查询商品列表】- 查询结果:${}$", searchHits);
// 获取到商品结果集
List<GoodsSpuEsOut> goodsSpuEsOutList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
return goodsSpuEsOutList;
}
文章评论