Springdataelasticsearch怎么用
创始人
2024-12-24 21:42:07
0次

一、准备

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

@Resourceprivate 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.注入

@Autowiredprivate 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));

● 自定义查询

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(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);}

KeywordSampleElasticsearch Query String

五、高级查询

● 词条查询

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 bucket : 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类型    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 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处理时忽略空值

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...