Elasticsearch笔记 (二)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch笔记 (二)

五.SpringDataElsticsearch#


SpringDataElasticsearch官方文档地址


这是原来画的图,JEST直接放弃了,让我们自己拼接json串,简直只有难受

终于到编码阶段,这部分相比前面的原生api看起来就好受多了,Spring一整合,啥东西都简单的只剩下两件事,1,写个配置文件,2.用它的方法,玩他的注解--, 当然我现在回顾学习的整个过程,最重要的是还是那句话,不要忘记了自己的需求,不然学着学着容易迷失,不知道自己想干啥,对于Elasticsearch吧先觉的它啥都能干,又觉得它啥也干不了,这是个很尴尬的事情! 那,我用它做全文检索,我就得去搞明白 知道下面那几件事


  1. 怎么搭建起开发环境,使我的java代码和ES交互
  2. spring整合它嘛,提供了哪些注解,表示我的javaBean是个document对象
  3. 如何建立索引库
  4. 基本的CRUD
  5. 花里胡哨的查询方法

下面挨个做这几件事!


5.1 搭建开发环境#


坐标


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>


配置文件(java和它的交互走的是tcp协议)


spring:
  application:
    name: search-service
  data:
    elasticsearch:
      cluster-nodes: 192.168.43.150:9300
      cluster-name: elasticsearch


启动类


5.2实体类及注解#


实体类在java中就像是接盘侠,啥样的东东,它都有能给接下来,看完了下面的注解,就知道了如何把数据存进es认识的实体类,准备把他们存在索引库


import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
@Document(indexName="changwu",type = "item",shards = 1)
public class Item {
    @Id
    @Field(type=FieldType.Long)
    Long id;
    @Field(type = FieldType.Text,analyzer = "ik_smart")
    String title; //标题
    @Field(type=FieldType.Keyword,index = true)
    String category;// 分类
    @Field(type=FieldType.Keyword)
    String brand; // 品牌
    @Field(type=FieldType.Double)
    Double price; // 价格
    @Field(type=FieldType.Keyword,index = false)
    String images; // 图片地址
    // 指定存储时和检索时使用的分词器是同一个
    // index=true 表示索引
    // 是否索引, 就是看这个字段是否能被搜索, 比如: 如果对整篇文章建立了索引,那么从文章中任意抽出一段来,都可以搜索出这个文章
    // 是否分词, 就是表示搜索的时候,是整体匹配还是单词匹配  比如: 如果不分词的话,搜索时,一个词不一样,都搜索不出来结果
    // 是否存储, 就是,是否在页面上展示 , 但是在es中默认字段值已经存储在_source 字段里, 也是能检索出原始字段的
    @Field(index = true, store = true,type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
    private String title;
    /**
     * analyzer 存进去的时候,按这个分词
     * searchAnalyzer: 搜索时,按这个分词
     */
    @Field(index = true, store = true, type = FieldType.Text ,analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
    private String content;
    @Field(index = true,type = FieldType.Keyword)
    private String state;
}


  • @Document
  1. 作用在类,标记实体类为文档对象
  • indexName:对应索引库名称---- 数据库名
  • type:对应在索引库中的类型---- 表名
  • shards:分片数量,默认5
    -replicas:副本数量,默认1


  • @Id
  1. 作用在成员变量id上
  • 标记一个字段作为id主键(这个id别写错了,不然程序都启动不起来)


  • @Field
  1. 作用在成员变量,标记为文档的字段,并指定字段映射属性:
  • type:字段类型,取值是枚举:FieldType
  • index:是否索引,布尔类型,默认是true
  • store:是否存储,布尔类型,默认是false
  • analyzer:分词器名称

另外不要忘记了它的智能推断,如果我们不在字段上添加@Field,他根据值的类型进行推断


比如: 下面三个都会被推断为long类型,


private Long cid3;//  
private Date createTime;//  
private List<Long> price;//


5.3 创建索引库#


索引库的创建放到text里面就ok了


  • 使用的是ElasticsearchTemplate,Spring一直都是这样,整合完了,给你个模板

创建索引,添加映射,删除索引


template.createIndex(Goods.class);
template.putMapping(Goods.class);
template.deleteIndex()


5.4 基本的CRUD#


SpringData的强大之后就是,我们不再去写dao层了,她会通过反射给我们写好,有点Mybatis里面的通用mapper的意思,但是它更强大,---你给方法名它自动的生成方法


public interface GoodsRepository extends ElasticsearchRepository<Goods,Long> {}


使用 repository点一下,findXX saveXXX, deleteXXX全出来了,不再细说

另外:

点击进入如何自定义方法,Spring给实现

如果可以看懂原生的语法,那么对他的使用就不多说了...就是无脑使用


到了这,就知道了如何把通过java代码,对索引库里面的数据进行简单的增删改查


5.5 着重看一下如何进行繁杂查询#


真正使用es的时候,Repository里面的方法可以满足大部分的功能,但是聚合,过滤的话,只能使用原生的API

假设我们有下面的需求: 前端把用户需要搜索的信息收集起来了--全文检索


  • 全文检索


/**
 * 全文检索
 */
@Test
public void textQuery(){
    //创建查询构建器
    NativeSearchQueryBuilder QueryBuilder = new NativeSearchQueryBuilder();
    /**
     * 给查询构造器添加条件
     *   1. 它仍然需要的是一个  QueryBuilder ,通过QueryBuilders里面的静态方法创建,间接继承了QueryBuild
     *   2. 可也看到,基本上所有常用的条件查询都有了, bool , 词条term , match , 模糊查询 fuzzy
     *   3. 我们也可以抽出来一个方法, 方法里使用bool查询, 他支持先添加查询,紧接着过滤,  还记不记得那个  match{},filter:{}
     *    3.1 注意区分开结果过滤_source 和 filter
     *
     *         matchQuery     @Param field
     *         matchQuery     @Param field的值
     *   */
    QueryBuilder.withQuery(QueryBuilders.matchQuery("title","小米"));
    /**
     * 结果过滤
     * @Param : SourceFilter  ,但是它是和接口,于是我用它唯一的实现类
     */
    QueryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{"title","price"},null));
    /**
     * 排序
     */
    QueryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
    /**
     * 分页
     *  原生的api使用下面两个字段控制
     *  "from": 0,
     *  "size":10
     *  但是注意,他是的第一页是0
     * @Param : Pageable 他是个接口,我们使用它的实现类  PageRequest(静态方法of)
     */
    QueryBuilder.withPageable(PageRequest.of(1,10));
    Page<Goods> result = repository.search(QueryBuilder.build());  //它仍然需要的是一个QueryBuilder , 通过构造器.build()构建出来
    //解析结果
    long elements = result.getTotalElements();
    int totalPages = result.getTotalPages();
    List<Goods> content = result.getContent();
}
/**
 * 创建基本的查询条件
 * 创建布尔查询,
 *  一部分当作查询条件(must)
 *  一部分当作过滤条件(filter)
 * @param searchRequest
 * @return QueryBuilder 给QueryBuild.withQuery()使用
 */
private QueryBuilder buildBasicQuery(SearchRequest searchRequest) {
    //创建布尔查询
    BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    //查询条件
    queryBuilder.must(QueryBuilders.matchQuery("字段名",字段值));
    if(过滤条件){
    /*
    *把处理好的字段,传给过滤器 过滤
    *@param name  The name of the field
    *@param value The value of the term
    */ 
    queryBuilder.filter(QueryBuilders.termQuery(字段名,字段值));
    }
return  queryBuilder;
}


  • 聚合查询


/**
   * 聚合查询
   */
@Test
public void textAgg(){
    //同样少不了 查询构造器
    NativeSearchQueryBuilder QueryBuilder = new NativeSearchQueryBuilder();
    /**
     * 添加聚合add, 可以聚合多次
     * @Param AbstractAggregationBuilder 它间接继承与 AggregationBuilder 我们下面的工具类
     *
     * AggregationBuilders下面基本上涵盖了我们所有的聚合方式
     */
    QueryBuilder.addAggregation(AggregationBuilders.terms("popular_brand").field("brand"));
    /**
     * 推荐使用和这个,支持聚合查询,并返回带聚合的结果
     * @Param :SearchQuery
     * @Param :Class<T>
     * @Return:
     */
    AggregatedPage<Goods> result = template.queryForPage(QueryBuilder.build(), Goods.class);
    /**
     * 解析聚合
     *
     */
    Aggregations aggregations = result.getAggregations();
    // 获取指定名称 聚合
    //Aggregations agg = aggregations.get("popular_brand");
    StringTerms agg = aggregations.get("popular_brand");
    /**
     * 问题来了,  不存在 agg.getBuckets()
     * 原因看上面的图,是 Aggregations是个顶级接口,
     */
    List<StringTerms.Bucket> buckets = agg.getBuckets();
    //遍历buckets
    for (StringTerms.Bucket bucket : buckets) {
        System.out.println(bucket.getKeyAsString());
        System.out.println(bucket.getDocCount());
    }
}


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
8月前
|
安全
【Elasticsearch6】安装笔记
【Elasticsearch6】安装笔记
51 2
|
9月前
|
关系型数据库 MySQL 索引
|
9月前
|
前端开发 Java iOS开发
elasticsearch8.1源码编译笔记
elasticsearch8.1源码编译笔记
156 0
|
9月前
|
自然语言处理 安全 关系型数据库
|
JSON 安全 搜索推荐
白日梦的Elasticsearch实战笔记,32个查询案例、15个聚合案例、7个查询优化技巧(一)
白日梦的Elasticsearch实战笔记,32个查询案例、15个聚合案例、7个查询优化技巧(一)
1140 1
|
Java 数据库 Docker
Elasticsearch笔记
Elasticsearch笔记
173 0
Elasticsearch笔记
|
存储 Web App开发 搜索推荐
Elasticsearch笔记(集群插件、kibana、什么是倒排索引)
Elasticsearch笔记(集群插件、kibana、什么是倒排索引)
Elasticsearch笔记(集群插件、kibana、什么是倒排索引)
Elasticsearch核心技术与实战-极客课程笔记
Elasticsearch核心技术与实战-极客课程笔记
588 0
Elasticsearch核心技术与实战-极客课程笔记
|
搜索推荐
ElasticSearch笔记
ElasticSearch笔记
149 0
ElasticSearch笔记
|
SQL 缓存 自然语言处理
白日梦的Elasticsearch实战笔记,32个查询案例、15个聚合案例、7个查询优化技巧(二)
白日梦的Elasticsearch实战笔记,32个查询案例、15个聚合案例、7个查询优化技巧(二)
1031 1

热门文章

最新文章