ElasticSearch系列四 CURD

Stella981
• 阅读 550

https://www.cnblogs.com/dgwblog/p/12382173.html

1: ES 类似JPA操作

1.1 编写实体类

1.2 编写映射文件 xxx.json

1.3编写repository继承 ElasticSearchrepository

1.4 编写admin 的CRUD

2: 使用ElasticSearchtemplate 对索引操作

2.1 对索引的各类操作

3: 高级查询

配置application

##es 单个ES地址 #spring.data.elasticsearch.cluster-nodes= ## 设置ES多个地址 
spring.data.elasticsearch.client.reactive.endpoints=[http://localhost:9200] ## 
开启repositories spring.data.elasticsearch.repositories.enabled=true 
#spring.data.elasticsearch.client.reactive.connection-timeout= 
#spring.data.elasticsearch.client.reactive.password= 
#spring.data.elasticsearch.client.reactive.socket-timeout= 
#spring.data.elasticsearch.client.reactive.username= ##es  单个ES地址
#spring.data.elasticsearch.cluster-nodes=
##  设置ES多个地址
spring.data.elasticsearch.client.reactive.endpoints=[http://localhost:9200]
## 开启repositories
spring.data.elasticsearch.repositories.enabled=true
#spring.data.elasticsearch.client.reactive.connection-timeout=
#spring.data.elasticsearch.client.reactive.password=
#spring.data.elasticsearch.client.reactive.socket-timeout=
#spring.data.elasticsearch.client.reactive.username=

pom依赖

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

1: ES 类似JPA操作

1.1 编写实体类

// indexName: 索引名称  type: 执行数据库类型的表
@Document(indexName = "esadmin",type = "admin")
@Mapping(mappingPath = "admin_es.json") //指向映射文件
public class Admin {

    @Id
    private Long id;
    private String username;
    private String password;
    private String loveThings;
    // getter setter 方法

1.2 编写映射文件 xxx.json

{
  "properties": {
    "id": {
      "type": "long"
    },
    "username": {
      "type": "string",
      "index":    "not_analyzed"
    },
    "password": {
      "type": "string",
      "index":    "not_analyzed"
    },
    "loveThings": {
      "type": "text",
      "analyzer": "ik_max_word",
      "search_analyzer": "ik_max_word"
    }
  }
}

1.3编写repository继承 ElasticSearchrepository

@Repository public interface AdminRepository extends 
ElasticsearchRepository&lt;Admin,Long&gt; { }

1.4 编写admin 的CRUD

@RestController
public class AdminController {

    @Autowired
    private AdminRepository adminRepository;

    // http://localhost:8080/saveOrUpdate

    /**
     *  send data
     * {
     *     "username":"dgw3",
     *     "password":"root",
     *     "loveThings":"postman(二):使用postman发送get or post请"
     * }
     */
    @PostMapping("saveOrUpdate")
    public String saveOrUpdate(@RequestBody Admin admin){
        if(admin.getId()==null){
            admin.setId(System.currentTimeMillis());
        }
        adminRepository.save(admin);
        return "保存成功";
    }
    //http://localhost:8080/delete?id=1582946734759
    @GetMapping("delete")
    public String delete(Long id){
        try {
            adminRepository.deleteById(id);
        } catch (Exception e) {
            e.printStackTrace();
            return "删除失败";
        }
        return "删除成功";
    }
    //http://localhost:8080/findById?id=1582946734759
    @GetMapping("findById")
    public Admin findById(long id){
        Optional<Admin> admin = adminRepository.findById(id);
        if(admin.isPresent()){
            return admin.get();
        }else{
            return null;
        }
    }
    //http://localhost:8080/findAll
    @GetMapping("findAll")
    public Iterable<Admin> findAll(){
            return adminRepository.findAll();
    }
}

2: 使用ElasticSearchtemplate 对索引操作

2.1 对索引的各类操作

@RestController
public class ElasticOperationControler {

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @GetMapping("createIndex")
    public boolean createIndex(String indexName){
        return elasticsearchTemplate.createIndex(indexName);
    }

    @GetMapping("deleteIndex")
    public boolean deleteIndex(String indexName){
        return elasticsearchTemplate.deleteIndex(indexName);
    }

    @GetMapping("indexIsExist")
    public boolean indexIsExist(String indexName){
        return elasticsearchTemplate.indexExists(indexName);
    }

    @GetMapping("typeIsExist")
    public boolean typeIsExist(String indexName,String type){
        return elasticsearchTemplate.typeExists(indexName,type);
    }

    @GetMapping("getMapping")
    public Map getMapping(String indexName, String type){
        return elasticsearchTemplate.getMapping(indexName,type);
    }

    @GetMapping("getSetting")
    public Map getSetting(String indexName){
        return elasticsearchTemplate.getSetting(indexName);
    }
}

3: 高级查询

查询步骤:

  • QueryBuilders 构建查询关键词

  • SortBuilders 构建对关键字的排序

  • NativeSearchQueryBuilder 对前两个条件进行封装,

  • Repository : 进行查询

    @RestController public class SearchController {

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    
    @Autowired
    private ArticleRepository articleRepository;
    
    //1.不分词查询:查询articleContent带有你好 或者 articleName带有你好的文章列表,并且按照readCount倒叙排序
    //http://localhost:8080/query1?keyword=你好
    @GetMapping("query1")
    public List<Article> query1(String keyword) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    
        BoolQueryBuilder articleContent = boolQuery.should(QueryBuilders.termQuery("articleContent", keyword));
        BoolQueryBuilder articleName = boolQuery.should(QueryBuilders.termQuery("articleName", keyword));
    
        FieldSortBuilder order = SortBuilders.fieldSort("readCount").order(SortOrder.DESC);
    
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
    
        nativeSearchQueryBuilder.withQuery(articleContent);
        nativeSearchQueryBuilder.withQuery(articleName);
        nativeSearchQueryBuilder.withSort(order);
    
        NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
    
        Page<Article> articles = articleRepository.search(searchQuery);
        if (articles != null) {
            return articles.getContent();
        } else {
            return null;
        }
    }
    //2.不分词查询:查询articleContent带有我们 或者 你好 并且authorAge在20岁以下的文章列表,并且按照readCount倒叙排序
    //http://localhost:8080/query11?keyword=你好,我们
    @GetMapping("query2")
    public List<Article> query2(String... keyword) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termsQuery("articleContent", keyword));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("authorAge").lt(20));
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("readCount").order(SortOrder.DESC);
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        nativeSearchQueryBuilder.withSort(fieldSortBuilder);
        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
        Page<Article> page = articleRepository.search(nativeSearchQuery);
        if (page != null) {
            return page.getContent();
        } else {
            return null;
        }
    }
    
    //3.分词查询:经过分词,查询articleContent带有你好节日一词分词后的文章列表,并且按照authorAge倒叙排序
    //http://localhost:8080/query12?keyword=你好节日
    @GetMapping("query3")
    public List<Article> query3(String keyword) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.should(QueryBuilders.matchQuery("articleContent", keyword));
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("authorAge").order(SortOrder.DESC);
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        nativeSearchQueryBuilder.withSort(fieldSortBuilder);
        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
        Page<Article> page = articleRepository.search(nativeSearchQuery);
        if (page != null) {
            return page.getContent();
        } else {
            return null;
        }
    }
    
    //4.分页分词查询:经过分词,查询articleContent带有你好节日一词分词后的文章列表,并且按照authorAge倒叙排序
    //http://localhost:8080/query13?keyword=你好节日&pageNum=1&pageSize=5
    @GetMapping("query4")
    public Page<Article> query4(String keyword, Integer pageNum, Integer pageSize) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.should(QueryBuilders.matchQuery("articleContent", keyword));
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("authorAge").order(SortOrder.DESC);
        PageRequest pageRequest = new PageRequest(pageNum, pageSize);
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        nativeSearchQueryBuilder.withSort(fieldSortBuilder);
        nativeSearchQueryBuilder.withPageable(pageRequest);
        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
        Page<Article> page = articleRepository.search(nativeSearchQuery);
        if (page != null) {
            return page;
        } else {
            return null;
        }
    }
    
    //5.分页分词查询:经过分词,查询articleContent带有你好节日一词分词后的文章列表,并且按照authorAge倒叙排序,并且对匹配到的词语设置为高亮
    //http://localhost:8080/query14?keyword=你好节日&pageNum=1&pageSize=5&fieldNames=articleContent,articleName
    @GetMapping("query5")
    public Map<String, Object> query5(String keyword, Integer pageNum, Integer pageSize, String... fieldNames) {
    
        //定义返回的map
        Map<String, Object> returnMap = new HashMap<String,Object>();
    
        // 不使用默认的分词器  直接操控索引
        //构建请求构建器,设置查询索引
        SearchRequestBuilder builder = elasticsearchTemplate.getClient().prepareSearch("testes");
    
        //构建查询构建器,设置分词器(如果没设置使用默认)
        QueryBuilder matchQuery = QueryBuilders.multiMatchQuery(keyword, fieldNames).analyzer("ik_max_word");
    
        //构建高亮构建器
        HighlightBuilder highlightBuilder = new HighlightBuilder().field("*").requireFieldMatch(false);
        highlightBuilder.preTags("<span style=\"color:red\">");
        highlightBuilder.postTags("</span>");
    
        //将高亮构建器,查询构建器,分页参数设置到请求构建器内
        builder.highlighter(highlightBuilder);
        builder.setQuery(matchQuery);
        builder.setFrom((pageNum - 1) * pageSize);
        builder.setSize(pageNum * pageSize);
        builder.setSize(pageSize);
    
        //执行搜索,返回搜索响应信息
        SearchResponse searchResponse = builder.get();
        SearchHits searchHits = searchResponse.getHits();
    
        //总命中数
        long total = searchHits.getTotalHits();
        returnMap.put("count", total);
    
        //将高亮字段封装到返回map
        SearchHit[] hits = searchHits.getHits();
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> map;
        for(SearchHit searchHit : hits){
            map = new HashMap<>();
            map.put("data",searchHit.getSourceAsMap());
            Map<String,Object> hitMap = new HashMap<>();
            searchHit.getHighlightFields().forEach((k,v) -> {
                String hight = "";
                for(Text text : v.getFragments()){
                    hight += text.string();
                }
                hitMap.put(v.getName(),hight);
            });
            map.put("highlight",hitMap);
            list.add(map);
        }
        returnMap.put("dataList", list);
        return returnMap;
    }
    
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这