【精华】小白都能看懂如何快速学习Elasticsearch。索引操作、新增数据、查询数据、聚合

本文详细介绍如何使用Spring Boot整合Elasticsearch,包括索引操作、数据增删改查、查询优化及聚合分析。通过具体示例,展示如何创建索引、映射实体类、新增和修改文档、执行基本和高级查询,以及进行分页、排序和聚合分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先导入Elasticsearch坐标
 <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>

1.索引操作

首先我们准备好实体类:

public class Item {
    private Long id;
    private String title; //标题
    private String category;// 分类
    private String brand; // 品牌
    private Double price; // 价格
    private String images; // 图片地址
}

我们要将实体类映射
实例:

@Document(indexName = "item",type = "docs", shards = 1, replicas = 0)
public class Item {
    @Id
   private Long id;

@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title; //标题

@Field(type = FieldType.Keyword)
private String category;// 分类

@Field(type = FieldType.Keyword)
private String brand; // 品牌

@Field(type = FieldType.Double)
private Double price; // 价格

@Field(index = false, type = FieldType.Keyword)
private String images; // 图片地址
}

创建索引
ElasticsearchTemplate中提供了创建索引的API:
在这里插入图片描述
• 可以根据类的信息自动生成,也可以手动指定indexName和Settings

映射相关的API:
在这里插入图片描述
• 一样,可以根据类的字节码信息(注解配置)来生成映射,或者手动编写映射

我们这里采用类的字节码信息创建索引并映射:
@Test
public void createIndex() {
    // 创建索引,会根据Item类的@Document注解信息来创建
    esTemplate.createIndex(Item.class);
    // 配置映射,会根据Item类中的id、Field等字段来自动完成映射
    esTemplate.putMapping(Item.class);
}

2.删除索引

可以根据类名或索引名删除。
示例:

@Test
public void deleteIndex() {
    esTemplate.deleteIndex(Item.class);
    // 根据索引名字删除
    //esTemplate.deleteIndex("item1");
}

3.新增文档数据

我们需要定义接口(相当于dao),然后继承它就OK了。

public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
}
3.1新增一个对象
@Autowired
private ItemRepository itemRepository;

@Test
public void index() {
    Item item = new Item(1L, "小米手机7", " 手机",
                         "小米", 3499.00, "http://image.baidu.com/13123.jpg");
    itemRepository.save(item);
}

去页面查询看看:
在这里插入图片描述

3.2批量新增
@Test
public void indexList() {
    List<Item> list = new ArrayList<>();
    list.add(new Item(2L, "坚果手机R1", " 手机", "锤子", 3699.00, "http://image.baidu.com/13123.jpg"));
    list.add(new Item(3L, "华为META10", " 手机", "华为", 4499.00, "http://image.baidu.com/13123.jpg"));
    // 接收对象集合,实现批量新增
    itemRepository.saveAll(list);
}

再次去页面查询:
在这里插入图片描述

4.修改

修改和新增是同一个接口,区分的依据就是id。

@Test
public void index(){
    Item item = new Item(1L, "苹果XSMax", " 手机",
            "小米", 3499.00, "http://image.baidu.com/13123.jpg");
    itemRepository.save(item);
}

查看结果:
在这里插入图片描述

5.查询

5.1基本查询

我们来试试查询所有:

@Test
public void query(){
    // 查询全部,并安装价格降序排序
    Iterable<Item> items = this.itemRepository.findAll(Sort.by("price").descending());
    for (Item item : items) {
        System.out.println("item = " + item);
    }
}
5.2自定义方法查询

先来看最基本的match query:

@Test
public void search(){
    // 构建查询条件
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    // 添加基本分词查询
    queryBuilder.withQuery(QueryBuilders.matchQuery("title", "小米手机"));
    // 搜索,获取结果
    Page<Item> items = this.itemRepository.search(queryBuilder.build());
    // 总条数
    long total = items.getTotalElements();
    System.out.println("total = " + total);
    for (Item item : items) {
        System.out.println(item);
    }
}
5.3分页查询

利用NativeSearchQueryBuilder可以方便的实现分页:

@Test
public void searchByPage(){
    // 构建查询条件
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    // 添加基本分词查询
    queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
    // 分页:
    int page = 0;
    int size = 2;
    queryBuilder.withPageable(PageRequest.of(page,size));
// 搜索,获取结果
Page<Item> items = this.itemRepository.search(queryBuilder.build());
// 总条数
long total = items.getTotalElements();
System.out.println("总条数 = " + total);
// 总页数
System.out.println("总页数 = " + items.getTotalPages());
// 当前页
System.out.println("当前页:" + items.getNumber());
// 每页大小
System.out.println("每页大小:" + items.getSize());

for (Item item : items) {
    System.out.println(item);
}
}

结果:
在这里插入图片描述

可以发现,Elasticsearch中的分页是从第0页开始。

5.4排序

排序也通用通过NativeSearchQueryBuilder完成:

@Test
public void searchAndSort(){
    // 构建查询条件
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    // 添加基本分词查询
    queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
// 排序
queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));

// 搜索,获取结果
Page<Item> items = this.itemRepository.search(queryBuilder.build());
// 总条数
long total = items.getTotalElements();
System.out.println("总条数 = " + total);

for (Item item : items) {
    System.out.println(item);
}
}
5.5 聚合

Elasticsearch中的聚合,包含多种类型,最常用的两种,一个叫桶,一个叫度量.
:就是对数据进行分组。
度量:分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在ES中称为度量

比较常用的一些度量聚合方式:
• Avg Aggregation:求平均值
• Max Aggregation:求最大值
• Min Aggregation:求最小值
• Percentiles Aggregation:求百分比
• Stats Aggregation:同时返回avg、max、min、sum、count等
• Sum Aggregation:求和
• Top hits Aggregation:求前几
• Value Count Aggregation:求总数
• ……
注意:在ES中,需要进行聚合、排序、过滤的字段其处理方式比较特殊,因此不能被分词。这里我们将color和make这两个文字类型的字段设置为keyword类型,这个类型不会被分词,将来就可以参与聚合

5.6 嵌套聚合,求平均值

代码:

@Test
public void testSubAgg(){
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    // 不查询任何结果
    queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
    // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
    queryBuilder.addAggregation(
        AggregationBuilders.terms("brands").field("brand")
        .subAggregation(AggregationBuilders.avg("priceAvg").field("price")) // 在品牌聚合桶内进行嵌套聚合,求平均值
    );
    // 2、查询,需要把结果强转为AggregatedPage类型
    AggregatedPage<Item> aggPage = (AggregatedPage<Item>) 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,即品牌名称  3.5、获取桶中的文档数量
        System.out.println(bucket.getKeyAsString() + ",共" + bucket.getDocCount() + "台");
    // 3.6.获取子聚合结果:
    InternalAvg avg = (InternalAvg) bucket.getAggregations().asMap().get("priceAvg");
    System.out.println("平均售价:" + avg.getValue());
}

}

结果:
在这里插入图片描述

在Java中操作Elasticsearch(ES)进行聚合查询以获取索引数据总数,可以使用Elasticsearch的Java客户端库。以下是一个示例代码,展示了如何使用Java客户端进行聚合查询以获取索引数据总数: 首先,确保你已经添加了Elasticsearch的Java客户端库到你的项目中。如果你使用Maven,可以在`pom.xml`中添加以下依赖: ```xml <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.10.2</version> </dependency> ``` 然后,你可以使用以下代码进行聚合查询: ```java import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.builder.SearchSourceBuilder; public class ESDocumentCount { public static void main(String[] args) { // 创建Elasticsearch客户端 RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); try { // 创建搜索请求 SearchRequest searchRequest = new SearchRequest("your_index_name"); // 创建搜索源构建器 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 使用聚合查询获取总数 sourceBuilder.aggregation(AggregationBuilders.count("count").field("your_field_name")); // 设置搜索源 searchRequest.source(sourceBuilder); // 执行搜索请求 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 获取聚合结果 Terms agg = searchResponse.getAggregations().get("count"); long docCount = agg.getBuckets().get(0).getDocCount(); // 输出总数 System.out.println("Total document count: " + docCount); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭客户端 try { client.close(); } catch (Exception e) { e.printStackTrace(); } } } } ``` 在这个示例中,我们首先创建了一个`RestHighLevelClient`实例,然后构建了一个搜索请求并设置了聚合查询以获取索引数据总数。最后,我们执行搜索请求并输出总数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值