Spring data elasticsearch使用方法详解

网友投稿 482 2022-12-15


Spring data elasticsearch使用方法详解

这篇文章主要介绍了Spring data elasticsearch使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

一、准备

1.添加依赖

org.springframework.boot

spring-boot-starter-data-elasticsearch

2.application.yml

spring:

application:

name: search-service

data:

elasticsearch:

cluster-name: elasticsearch

cluster-nodes: 192.168.25.129:9300

3.实体类

@Data

@Document(indexName = "goods", type = "_doc", shards = 1, replicas = 0)

public class Goods {

@Idprivate Long id;

@Field(type = FieldType.text, analyzer = "ik_max_word")

private String all;

@Field(type = FieldType.keyword, index = false)

private String subTitle;private Long brandId;private Long cid1;private Long cid2;private Long cid3;private Date createTime;private List price;

@Field(type = FieldType.keyword, index = false)

private String skus;private Map specs;

}

@Document 作用在类,标记实体类为文档对象,一般有两个属性

indexName:对应索引库名称

type:对应在索引库中的类型

shards:分片数量,默认5

replicas:副本数量,默认1

@Id 作用在成员变量,标记一个字段作为id主键

@Field 作用在成员变量,标记为文档的字段,并指定字段映射属性:

type:字段类型,取值是枚举:FieldType

index:是否索引,布尔类型,默认是true

store:是否存储,布尔类型,默认是false

analyzer:分词器名称

二.、索引操作

首先注入ElasticsearchTemplate

@Resource

private ElasticsearchTemplate elasticsearchTemplate;

● 创建索引

elasticsearchTemplate.createIndex(Goods.class);

● 配置映射

elasticsearchTemplate.putMapping(Goods.class);

● 删除索引

//根据类

elasticsearchTemplate.deleteIndex(Goods.class);

//根据索引名

elasticsearchTemplate.deleteIndex("goods");

三、文档操作

1.定义接口。也是SpringData风格

public interface ItemRepository extends ElasticsearchRepository {

}

2.注入

@Autowired

private ItemRepository itemRepository;

● 新增文档

Item item = new Item(1L, "小米手机7", " 手机",

"小米", 3499.00, "http://image.leyou.com/13123.jpg");

itemRepository.save(item);

● 批量新增

List list = new ArrayList<>();

list.add(new Item(2L, "坚果手机R1", " 手机", "锤子", 3699.00, "http://image.leyou.com/123.jpg"));

list.add(new Item(3L, "华为META10", " 手机", "华为", 4499.00, "http://image.leyou.com/3.jpg"));

// 接收对象集合,实现批量新增

itemRepository.saveAll(list);

四、 基本搜索

● 基本查询。

例:

// 查询全部,并安装价格降序排序

Iterable items = this.itemRepository.findAll(Sort.by(Sort.Direction.DESC, "price"));

items.forEach(item-> System.out.println(item));

● 自定义查询

Keyword

Sample

Elasticsearch Query String

And

fhttp://indByNameAndPrice

{"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}

Or

findByNameOrPrice

{"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}

Is

findByName

{"bool" : {"must" : {"field" : {"name" : "?"}}}}

Not

findByNameNot

{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}

Between

findByPriceBetween

{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}

LessThanEqual

findByPriceLessThan

{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}

GreaterThanEqual

findByPriceGreaterThan

{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}

Before

findByPriceBefore

{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}

After

findByPriceAfter

{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}

Like

findByNameLike

{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}

StartingWith

findByNameStartingWith

{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}

EndingWith

findByNameEndingWith

{"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}

Contains/Containing

findByNameContaining

{"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}}

In

findByNameIn(Collectionnames)

{"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}

NotIn

findByNameNotIn(Collectionnames)

{"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}

Near

findByStoreNear

Not Supported Yet !

True

findByAvailableTrue

{"bool" : {"must" : {"field" : {"available" : true}}}}

False

findByAvailableFalse

{"bool" : {"must" : {"field" : {"available" : false}}}}

OrderBy

findByAvailableTrueOrderByNameDesc

{"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}

例:

public interface ItemRepository extends ElasticsearchRepository {

/**

* 根据价格区间查询

* @param price1

* @param price2

* @return

*/

List findByPriceBetween(double price1, double price2);

}

五、高级查询

● 词条查询

MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("all", "小米");

// 执行查询

Iterable goods = this.goodsRepository.search(queryBuilder);

● 自定义查询

// 构建查询条件

NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

// 添加基本的分词查询

queryBuilder.withQuery(QueryBuilders.matchQuery("all", "小米"));

// 执行搜索,获取结果

Page goods = this.goodsRepository.search(queryBuilder.build());

// 打印总条数

System.out.println(goods.getTotalElements());

// 打印总页数

System.out.println(goods.getTotalPages());

● 分页查询

// 构建查询条件

NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

// 添加基本的分词查询

queryBuilder.withQuery(QueryBuilders.termQuery("all", "手机"));

// 初始化分页参数

int page = 0;

int size = 3;

// 设置分页参数

queryBuilder.withPageable(PageRequest.of(page, size));

// 执行搜索,获取结果

Page goods = this.goodsRepository.search(queryBuilder.build());

// 打印总条数

System.out.println(goods.getTotalElements());

// 打印总页数

System.out.println(goods.getTotalPages());

// 每页大小

System.out.println(goods.getSize());

// 当前页

System.out.println(goods.getNumber());

● 排序

// 构建查询条件

NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

// 添加基本的分词查询

queryBuilder.withQuery(QueryBuilders.termQuery("all", "手机"));

// 排序

queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));

// 执行搜索,获取结果

Page goods = this.goodsRepository.search(queryBuilder.build());

// 打印总条数

System.out.println(goods.getTotalElements());

● 聚合为桶

NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

// 不查询任何结果

queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));

// 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand

queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brandId"));

// 2、查询,需要把结果强转为AggregatedPage类型

AggregatedPage aggPage = (AggregatedPage) this.goodsRepository.search(queryBuilder.build());

// 3、解析

// 3.1、从结果中取出名为brands的那个聚合,

// 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型

LongTerms agg = (LongTerms) aggPage.getAggregation("brands");

// 3.2、获取桶

List buckets = agg.getBuckets();

// 3.3、遍历

for (LongTerms.Bucket buckhttp://et : buckets) {

// 3.4、获取桶中的key,即品牌名称

System.out.println(bucket.getKeyAsString());

// 3.5、获取桶中的文档数量

System.out.println(bucket.getDocCount());

}

● 嵌套聚合,求平均值

NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

// 不查询任何结果

queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));

// 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand

queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brandId")

.subAggregation(AggregationBuilders.avg("priceAvg").field("price"))); // 在品牌聚合桶内进行嵌套聚合,求平均值

// 2、查询,需要把结果强转为AggregatedPage类型

Aggreghttp://atedPage aggPage = (AggregatedPage) this.goodsRepository.search(queryBuilder.build());

// 3、解析

// 3.1、从结果中取出名为brands的那个聚合,

// 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型

LongTerms agg = (LongTerms) aggPage.getAggregation("brands");

// 3.2、获取桶

List buckets = agg.getBuckets();

// 3.3、遍历

for (LongTerms.Bucket bucket : buckets) {

// 3.4、获取桶中的key,即品牌名称 3.5、获取桶中的文档数量

System.out.println(bucket.getKeyAsString() + ",共" + bucket.getDocCount() + "台");

// 3.6.获取子聚合结果:

InternalAvg avg = (InternalAvg) bucket.getAggregations().asMap().get("priceAvg");

System.out.println("平均售价:" + avg.getValue());

}

附:配置搜索结果不显示为null字段:

spring:

jackson:

default-property-inclusion: non_null # 配置json处理时忽略空值


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解决springboot 连接 mysql 时报错 using password: NO的方案
下一篇:Java binarysearch方法原理详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~