@RunWith(SpringRunner.class)
@SpringBootTest(classes = ItcastElasticsearchApplication.class)
public class IndexTest {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate; //注入ElasticsearchTemplate类
@Test
public void testCreate(){
// 创建索引,会根据Item类的@Document注解信息来创建
elasticsearchTemplate.createIndex(Item.class);
// 配置映射,会根据Item类中的id、Field等字段来自动完成映射
elasticsearchTemplate.putMapping(Item.class);
}
}
创建过索引和映射后,通过GET /item
指令进行测试:
删除索引: 可以根据类名或索引名删除。
@Test
public void testDelete(){
this.elasticsearchTemplate.deleteIndex(Item.class);
this.elasticsearchTemplate.deleteIndex(“item”);
}
Repository文档操作
Spring Data 的强大之处,就在于你不用写任何DAO处理,自动根据方法名或类的信息进行CRUD操作。只要你定义一个接口,然后继承Repository提供的一些子接口,就能具备各种基本的CRUD功能。
我们只需要定义接口,然后继承它就可以使用了:
public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
}
Repository的继承关系:
新增文档:
@Autowired
private ItemRepository itemRepository;
@Test
public void testCreate() {
Item item = new Item(1L, “小米手机10”, " 手机",
“小米”, 3499.00, “http://image.ly.com/13123.jpg”);
this.itemRepository.save(item);
}
去页面查询看看:GET /item/_search
结果:
批量新增:
代码:
@Test
public void testCreateList() {
List list = new ArrayList<>();
list.add(new Item(2L, “苹果手机”, " 手机", “iPhone”, 3699.00, “http://image.ly.com/123.jpg”));
list.add(new Item(3L, “华为META10”, " 手机", “华为”, 4499.00, “http://image.ly.com/3.jpg”));
list.add(new Item(4L, “华为电视”, " 电视", “华为”, 8499.00, “http://image.ly.com/856.jpg”));
// 接收对象集合,实现批量新增
itemRepository.saveAll(list);
}
再次去页面查询:
基本查询:ElasticsearchRepository提供了一些基本的查询方法
测试查询所有:
//根据id查询
@Test
public void testFind(){
Optional item = this.itemRepository.findById(1l);
System.out.println(item.get());
}
//测试查询所有,并降序排列
@Test
public void testFindAll(){
Iterable items = this.itemRepository.findAll(Sort.by(“price”).descending());
items.forEach(System.out::println);
}
结果:
自定义方法:Spring Data 的另一个强大功能,是根据方法名称自动实现功能。当然,方法名称要符合一定的约定。
| Keyword | Sample | Elasticsearch Query String |
| — | — | — |
| And
| findByNameAndPrice
| {"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(Collection<String>names)
| {"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
|
| NotIn
| findByNameNotIn(Collection<String>names)
| {"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}}}}
|
例如,根据title查询,或者按照价格区间查询,定义这样的一个方法,然后自动帮你完成,无需写实现类:
public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
/**
-
根据title查询
-
@param title
-
@return
*/
List findByTitle(String title);
/**
-
根据价格区间查询
-
@param d1
-
@param d2
-
@return
*/
List findByPriceBetween(Double d1,Double d2);
}
不需要写实现类,直接去运行:
@Test
public void testFindByPrice(){
List items =this.itemRepository.findByPriceBetween(3000d,4000d);
items.forEach(System.out::println);
}
结果:
高级查询
虽然基本查询和自定义方法已经很强大了,但是如果是复杂查询(模糊、通配符、词条查询等)就显得力不从心了。此时,我们只能使用原生查询。
基本用法:
@Test
public void testSearch(){
MatchQueryBuilder queryBuilder= QueryBuilders.matchQuery(“title”,“手机”);
Iterable items = this.itemRepository.search(queryBuilder);
items.forEach(System.out::println);
}
Repository的search方法需要QueryBuilder参数,elasticSearch为我们提供了一个对象QueryBuilders:
QueryBuilders提供了大量的静态方法,用于生成各种不同类型的查询对象,例如:词条、模糊、通配符等QueryBuilder对象。
结果:
自定义查询:
先来看最基本的match query:
@Test
public void testNativeQuery(){
// 构建查询条件
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 添加基本的分词查询
queryBuilder.withQuery(QueryBuilders.matchQuery(“title”, “小米”));
// 执行搜索,获取结果
Page items = this.itemRepository.search(queryBuilder.build());
// 打印总条数
System.out.println(items.getTotalElements());
// 打印总页数
System.out.println(items.getTotalPages());
items.forEach(System.out::println);
}
NativeSearchQueryBuilder:Spring提供的一个查询条件构建器,帮助构建json格式的请求体
Page<item>
:默认是分页查询,因此返回的是一个分页的结果对象,包含属性:
-
totalElements:总条数
-
totalPages:总页数
-
Iterator:迭代器,本身实现了Iterator接口,因此可直接迭代得到当前页的数据
运行结果:
分页查询:利用NativeSearchQueryBuilder
可以方便的实现分页
@Test
public void testNativeQuery2(){
// 构建查询条件
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 添加基本的分词查询
queryBuilder.withQuery(QueryBuilders.termQuery(“category”, " 手机"));
// 初始化分页参数
int page = 0;
int size = 2;
// 设置分页参数
queryBuilder.withPageable(PageRequest.of(page, size));
// 执行搜索,获取结果
Page items = this.itemRepository.search(queryBuilder.build());
// 打印总条数
System.out.println(items.getTotalElements());
// 打印总页数
System.out.println(items.getTotalPages());
// 每页大小
System.out.println(items.getSize());
// 当前页
System.out.println(items.getNumber());
items.forEach(System.out::println);
}
结果:Elasticsearch中的分页是从第0页开始
排序:排序也通用通过NativeSearchQueryBuilder
完成
@Test
public void testSort(){
// 构建查询条件
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 添加基本的分词查询
queryBuilder.withQuery(QueryBuilders.termQuery(“category”, " 手机"));
// 排序
queryBuilder.withSort(SortBuilders.fieldSort(“price”).order(SortOrder.DESC));
// 执行搜索,获取结果
Page items = this.itemRepository.search(queryBuilder.build());
// 打印总条数
System.out.println(items.getTotalElements());
items.forEach(System.out::println);
}
结果:
桶聚合
聚合为桶:桶就是分组,比如这里我们按照品牌brand进行分组
@Test
public void testAgg(){
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 不查询任何结果
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{“”}, null));
// 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
queryBuilder.addAggregation(
AggregationBuilders.terms(“brands”).field(“brand”));
// 2、查询,需要把结果强转为AggregatedPage类型
AggregatedPage aggPage = (AggregatedPage) this.itemRepository.search(queryBuilder.build());
// 3、解析
// 3.1、从结果中取出名为brands的那个聚合,
// 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型
StringTerms agg = (StringTerms) aggPage.getAggregation(“brands”);
// 3.2、获取桶
List<StringTerms.Bucket> buckets = agg.getBuckets();
// 3.3、遍历
for (StringTerms.Bucket bucket : buckets) {
// 3.4、获取桶中的key,即品牌名称
System.out.println(bucket.getKeyAsString());
// 3.5、获取桶中的文档数量
System.out.println(bucket.getDocCount());
}
}
显示的结果:
关键API:
-
AggregationBuilders
:聚合的构建工厂类。所有聚合都由这个类来构建,看看他的静态方法:
-
AggregatedPage
:聚合查询的结果类。它是Page<T>
的子接口:
AggregatedPage
在Page
功能的基础上,拓展了与聚合相关的功能,它其实就是对聚合结果的一种封装,大家可以对照聚合结果的JSON结构来看。
而返回的结果都是Aggregation类型对象,不过根据字段类型不同,又有不同的子类表示
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
Kafka实战笔记
关于这份笔记,为了不影响大家的阅读体验,我只能在文章中展示部分的章节内容和核心截图
- Kafka入门
- 为什么选择Kafka
- Karka的安装、管理和配置
- Kafka的集群
- 第一个Kafka程序
afka的生产者
- Kafka的消费者
- 深入理解Kafka
- 可靠的数据传递
- Spring和Kalka的整合
- Sprinboot和Kafka的整合
- Kafka实战之削峰填谷
- 数据管道和流式处理(了解即可)
- Kafka实战之削峰填谷
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!文章来源:https://www.toymoban.com/news/detail-851002.html
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算文章来源地址https://www.toymoban.com/news/detail-851002.html
ka的生产者
[外链图片转存中…(img-SeUhGYoT-1712186900204)]
- Kafka的消费者
- 深入理解Kafka
- 可靠的数据传递
[外链图片转存中…(img-T8xcuULZ-1712186900205)]
[外链图片转存中…(img-YTin8yfN-1712186900205)]
- Spring和Kalka的整合
- Sprinboot和Kafka的整合
- Kafka实战之削峰填谷
- 数据管道和流式处理(了解即可)
[外链图片转存中…(img-z1OrxUKZ-1712186900205)]
- Kafka实战之削峰填谷
[外链图片转存中…(img-H9buleLl-1712186900206)]
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
到了这里,关于SpringBoot整合Spring Data Elasticsearch,写给互联网大厂员工的真心话的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!