第六章:Elasticsearch入门

第六章:Elasticsearch入门,第1张

第六章:Elasticsearch入门 Elasticsearch入门

分布式搜索引

结构化、非结构化、地理位置。

搜索引擎搜索:1,提交数据到搜索引擎(它再存一份,它还会建立索引提高效率)

es中的索引-----》mysql中的数据库database

es中的类型----》mysql中的表table

es中的文档(数据结构为json)-----》msql中的一张表中的一行数据row

json当中的每一个属性叫字段------》mysql中的一列col

从6.0之后

es的索引----》mysql的表, 类型逐渐废弃

多台服务器构成集群,集群中的每台服务器称为节点,一个索引(一个表)数据很多,对索引进一步划分存储,并发能力提高,副本是对分片的备份。

修改配置

配置环境变量

将其bin目录加到系统的path下

下载分词postman

开启es

直接点击bin下面的bat

查看es集群的健康状态

查看结点

单节点

查看有多少索引

yellow不是最健康的状态,没有备份

删除索引

建立索引

插入数据

查询数据

改数据直接在body里面修改

删除数据

搜索

先插入几条数据

搜索

SpringBoot整合Elasticsearch


    org.springframework.boot
    spring-boot-starter-data-elasticsearch

解决redis和es的netty冲突问题

管理bean的生命周期,管理bean初始化的方法

@PostConstruct //解决netty启动冲突问题
public void init(){
    System.setProperty("es.set.netty.runtime.available.processors","false");
}

将贴子存到es服务器里面,我们去搜索帖子

配置帖子表和es索引的对应关系,每个字段对应什么样的类型,注解配置

将实体数据和es里面的数据进行映射,映射到那个索引,那个字段,那个分区,那个副本

分词器,拆分更可能多的词,用最聪明的分词器

dao里面定义接口

@Mapper是mybatis专用注解,@Repository是数据访问层使用的注解。继承spring默认接口es,加上泛型实体类和主键类型

创建测试类测试

从mysql数据库中取数据,再将其转存到es中。

先打开postman里面有没有帖子相关内容(服务器里面有哪些索引)

添加数据

(前提Kafka,zookeeper,es都启动)

查数据

Page不是我们自己写的类,是别人封装的

搜索测试类

@Test
public void testSearchTemplate(){
    SearchQuery searchQuery=new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬","title","content"))//搜索条件(即从title和content)
            .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))//排序条件(按照type是否置顶,score帖子分值,时间依次排序)
            .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
            .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
            .withPageable(PageRequest.of(0,10))//分页条件
            .withHighlightFields(
                    new HighlightBuilder.Field("title").preTags("").postTags(""),
                    new HighlightBuilder.Field("content").preTags("").postTags("")
            ).build();//哪些词高亮显示(前后置标签)

    Page page = elasticTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchResultMapper() {
        @Override
        public  AggregatedPage mapResults(SearchResponse response, Class aClass, Pageable pageable) {
            SearchHits hits=response.getHits();
            if(hits.getTotalHits()<=0){
                return null;
            }

            //遍历命中的数据
            List list=new ArrayList<>();
            for (SearchHit hit : hits) {
                DiscussPost post=new DiscussPost();
                //将数据包装到实体类返回(在hit里将json封装成了map)
                String id = hit.getSourceAsMap().get("id").toString();
                post.setId(Integer.valueOf(id));//将字符串id转为数字

                String userId = hit.getSourceAsMap().get("userId").toString();
                post.setUserId(Integer.valueOf(userId));
                //获得原始的title,content(可能里面没有关键词在content里)
                String title = hit.getSourceAsMap().get("title").toString();
                post.setTitle(title);

                String content = hit.getSourceAsMap().get("content").toString();
                post.setContent(content);

                String status = hit.getSourceAsMap().get("status").toString();
                post.setStatus(Integer.valueOf(status));

                //日期是long类型的字符串,将其先转为long再转为日期
                String createTime = hit.getSourceAsMap().get("createTime").toString();
                post.setCreateTime(new Date(Long.valueOf(createTime)));

                //处理高亮显示的结果
                //(获得高亮显示的内容)
                HighlightField titleField = hit.getHighlightFields().get("title");
                if(titleField!=null){
                    //不为空,重新设置title(只要第一个高亮部分)
                    post.setTitle(titleField.getFragments()[0].toString());
                }

                HighlightField contentField = hit.getHighlightFields().get("content");
                if(contentField!=null){
                    post.setContent(contentField.getFragments()[0].toString());
                }

                list.add(post);

            }

            return new AggregatedPageImpl(list,pageable,
                    hits.getTotalHits(),response.getScrollId(),hits.getMaxScore());
        }
    });

    //多少行,多少页,当前在哪一页,当前页显示了多少条数据
    System.out.println(page.getTotalElements());
    System.out.println(page.getTotalPages());
    System.out.println(page.getNumber());
    System.out.println(page.getSize());
    for (DiscussPost post : page) {
        System.out.println(post);
    }
}

开发社区搜索功能

//搜索表现层(传入关键词,分页自己封装的page)
//get请求参数不能用请求体来传,用路径后加?,用路径中的某一级来传
//search?keyword=xxx
@RequestMapping(path = "/search",method = RequestMethod.GET)
public String search(String keyword, Page page, Model model){
    //搜索帖子集合,es里面的当前页是从0开始,我们封装的page是从1开始,减1
    org.springframework.data.domain.Page discussPosts =
            elasticsearchService.searchDiscussPost(keyword, page.getCurrent() - 1, page.getLimit());
    //聚合需要的数据
    List> searchList=new ArrayList<>();

    //判断帖子搜索结果
    if(discussPosts!=null){
        //遍历搜索结果
        for (DiscussPost discussPost : discussPosts) {
            Map map=new HashMap<>();
            //将贴子、帖子作者、点赞数量存入map
            map.put("post",discussPost);
            map.put("user",userService.findUserById(discussPost.getUserId()));
            map.put("likeCount",likeService.findEntityLikeCount(ENTITY_TYPE_POST,discussPost.getId()));
            searchList.add(map);
        }

    }
    //将最终数据传给页面
    model.addAttribute("discussPosts",searchList);
    //关键词也传给模板页面
    model.addAttribute("keyword",keyword);

    //设置分页信息,路径、数据条数
    page.setPath("/search?keyword="+keyword);
    page.setRows(discussPosts==null?0:discussPosts.getTotalPages());

    return "/site/search";
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5688146.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存