springboot+elasticsearch+kibana整合本地搭建环境

springboot+elasticsearch+kibana整合本地搭建环境

准备

下载软件

elasticsearch-5.5.1
kibana-5.5.1
elasticsearch-analysis-ik-5.5.1
springboot 2.0.4.RELEASE

注意

版本必须是对应上的
1.下面是Springboot,Spring Data Elasticsearch,Elasticsearch的版本对应
在这里插入图片描述
2.elasticsearch ,kibana ,elasticsearch-analysis-ik 必须版本一致

安装 elasticsearch kibana

1.解压elasticsearch , kibana 到 D:\ELK目录

在这里插入图片描述

2.修改配置文件

** elasticsearch** :D:\ELK\elasticsearch-5.5.1\config\elasticsearch.yml

//主机地址
network.host: 192.168.63.248  
#network.hostbind_host: 192.168.63.248
#network.publish_host: 192.168.63.248
//http的端口
http.port: 9200
//服务通信的端口
transport.tcp.port: 9300
//集群名称
cluster.name: es_cluster_lmq
//节点名称
node.name: node-lmq-1

** kibana** : D:\ELK\kibana-5.5.1-windows-x86\config\kibana.yml

//端口 
server.port: 5601
//主机地址
server.host: "192.168.63.248"
//es的http的地址
elasticsearch.url: "http://192.168.63.248:9200/"
  1. 启动

启动es:D:\ELK\elasticsearch-5.5.1\bin\elasticsearch.bat,完成后 打开es的http地址,就能看到es一下信息,集群名,版本等 http://192.168.63.248:9200/
在这里插入图片描述
再启动 kibana,es没启动,直接启动kibana会报错 http://192.168.63.248:5601
在这里插入图片描述
这样就算是 es和kibana搭建成功了

中文分词查询

es的默认分词器

首先说个例子
我要查询数据中 shortTitle包含 “旗舰店” 的数据,
1.那我就用模糊查询 wildcard , “shortTitle”:“旗舰店” 通配符查询,查询没有数据 图1
2.那我换个方式: “shortTitle.keyword”:"*旗舰店" ,就有数据了
这个原因是因为 shopTitle 是text的类型 是走分词,倒排索引的, shopTitle.keyword的类型需要全字段的精确匹配,
在这里插入图片描述

在这里插入图片描述

全文匹配不用说了, 字符串:“官网旗舰店” 用通配符查询,肯定是查询到数据的
text的类型的话,是会分词,查询的时候就检索分词后的每个词条,es的默认分词 是分成一个一个词,作为索引,这样的话,我拿 “旗舰店” 去匹配查询 一个一个词 肯定是查不到的

分词结果如下
在这里插入图片描述

ik中文分词器

上面准备工作已经下载下来了

引入到es

1.D:\ELK\elasticsearch-5.5.1\plugins 新建文件夹 ik
2.解压ik,把文件复制到 ik文件夹下面
在这里插入图片描述

重启es

控制台能看到 已加载了 ik了
在这里插入图片描述
ik分词器提供了两个模式的分词 ik_max_word(会将文本做最细粒度的拆分) ik_smart (会做最粗粒度的拆分) 分别看下分词效果 看到分词效果好很多了
在这里插入图片描述
在这里插入图片描述

再来模糊查询看看 ,因为我配置的 title字段是根据ik中文分词器,这样就能 根据分词后的 字条“旗舰店” 查询到了
在这里插入图片描述
有了中文分词的话 ,我们用的查询就用 match ,match 是先把查询的字符串进行分词(要自定义映射文件),然后再去查询分词索引的, 例如 是查询 “官网旗舰店” 分词后是 官, 网, 旗舰店,这样就能查询到,这些数据
,,只要包含了就能查询出来,

在这里插入图片描述
那我想查询 包含 网, 旗舰店,的数据呢,“operator”: “and” 就行了 就只会有一条数据
在这里插入图片描述

也可以查询看下一条数据单个字段的分词情况

get /ricer_shop_tbk_item/ricer_shop_tbk_item/580332176701/_termvectors?fields=shortTitle
get /indexName/indexType/数据的主键ID/_termvectors?fields=需要查询字段的 可以看到就是一个词一个词分的

在这里插入图片描述

get /ricer_shop_tbk_item/ricer_shop_tbk_item/580332176701/_termvectors?fields=title
title是配置了ik中文分词的 这样看来分词效果还不错

在这里插入图片描述

springboot+elasticsearch整合

引入jar包

	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
    </parent>

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

配置es服务地址 这里用的就是 9300 端口

  data:
    elasticsearch:
      cluster-name: es_cluster_lmq
      cluster-nodes: 192.168.63.248:9300

创建索引 通过注解配置

 	@Autowired
    private ItemRepository itemRepository;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
	 public void initESItem() {
		//删除索引
	    elasticsearchTemplate.deleteIndex(ESTbkItem.class);
	    //创建索引
	    elasticsearchTemplate.createIndex(ESTbkItem.class);
	    //加载动态映射
	    elasticsearchTemplate.putMapping(ESTbkItem.class);
	}
	
@Data
@NoArgsConstructor
@Accessors(chain = true)
@Mapping(mappingPath = "mapping/tbk_item_mapping.json")//配置自定义的映射文件
@Document(indexName = "ricer_shop_tbk_item", type = "ricer_shop_tbk_item",shards = 1,replicas = 0)
public class ESTbkItem implements Serializable {
	
 @Id
    private Long itemId;

    private Long categoryId;

    private String categoryName;
}

创建好了就能在kibana上查询索引的信息 es自身也是可以查询的http://192.168.63.248:9200/_mapping/ricer_shop_tbk_item
在这里插入图片描述
我这操作es的数据的话 是通过 ElasticsearchRepository 来操作的


//添加数据如下 (增删改 jpa都一样的)
List<ESTbkItem> esTbkItems = Lists.newArrayList();
itemRepository.saveAll(esTbkItems);
//下面说下查询 


    public Page<ESTbkItem> findByParams(Map<String, Object> param) {
        log.info("findByParams:" + JSONObject.toJSONString(param));
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

       	//排序
        Sort sort = sortBuilder(param.get("orderByColumn") == null ? "":param.get("orderByColumn").toString());
        //分页
        Pageable pageable = PageRequest.of(Integer.valueOf(param.get("pageNo").toString()) - 1, Integer.valueOf(param.get("pageSize").toString()), sort);

        queryBuilder.withPageable(pageable);
        //
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        if (Objects.nonNull(param.get("itemName"))) {
        //添加ik分词插件  分词查询
        // boolQueryBuilder.must(QueryBuilders.matchQuery("title", param.get("itemName"));
            //不进行分词,模糊查询
            boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("title", param.get("itemName")));
        }
        if (Objects.nonNull(param.get("category"))) {
        //精确查询
            boolQueryBuilder.must(QueryBuilders.termQuery("categoryId", param.get("category")));
        }
		// in 
        if (Objects.nonNull(param.get("categorys"))) {
            List<Long> categorys = (List<Long>) param.get("categorys");
            boolQueryBuilder.must(QueryBuilders.termsQuery("categoryId", categorys));
        }

		// 大于
        if (Objects.nonNull(param.get("couponUsedRateStart"))) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("couponUsedRate").gt(param.get("couponUsedRateStart")));
        }
		// 小于
        if (Objects.nonNull(param.get("couponUsedRateEnd"))) {
            boolQueryBuilder.must(QueryBuilders.rangeQuery("couponUsedRate").lt(param.get("couponUsedRateEnd")));
        }
        queryBuilder.withQuery(boolQueryBuilder);
        return itemRepository.search(queryBuilder.build());
    }


	//构建 orderby
    private Sort sortBuilder(String orderByColumn) {
        List<Sort.Order> list = Lists.newArrayList();
        if (Objects.isNull(orderByColumn)) {
        //默认排序字段
            Sort.Order order = new Sort.Order(Sort.Direction.DESC, "volume");
            list.add(order);
        } else {
        //多字段排序 "price:desc,volume:asc"
            String[] orderByColumn_arr = orderByColumn.split(",");
            for (String s : orderByColumn_arr) {
                String[] colum_arr = s.split(":");
                if (colum_arr.length == 2) {
                    Sort.Order order = new Sort.Order(colum_arr[1].equals("asc") ? Sort.Direction.ASC : Sort.Direction.DESC, colum_arr[0]);
                    list.add(order);
                }

            }
        }
        Sort sort = new Sort(list);
        return sort;
    }

springboot+ ik中文分词器

自定义映射文件 ps:如果改过映射文件,需要删除索引 ,重新加载,不然不会生效的

{
"properties": {
//可以只对单个的字段进行配置,未配置的字段是默认配置的  
"title": {//配置字段 title
    "type": "text",
    "fields": {
      "keyword": {
        "type": "keyword",
        "ignore_above": 256
      }
    },
    "analyzer": "ik_max_word",//查询数据是 按照最细的分词
    "search_analyzer": "ik_smart"//查询数据时,按照最粗的来分词
  }
}
}

get ricer_shop_tbk_item/_mapping 可以看到映射文件已经生效了

在这里插入图片描述

ElasticsearchTemplate 查询实现查询结果高亮显示

上代码

		Integer pageSize = 10;
        Integer pageNo   = 1;
        Pageable pageable                 = PageRequest.of(pageNo - 1, pageSize);
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withPageable(pageable);
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        if (StringUtils.isNotEmpty(textLike)) {
            boolQueryBuilder.must(matchQuery("title", textLike).operator(Operator.AND));//分词后,查询结果是并且的意思,例如  查询 培根汉堡 ,查询处理的数据中,是包含 培根+汉堡的,需要查询或者的话就是  就是Operator.OR
            nativeSearchQueryBuilder.withHighlightFields(new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"));//标记title查询结果需要高亮,  <em> </em>  是匹配出来的词前后的标签,自定义替换的
        }


        SortOrder sortOrder = SortOrder.DESC;
        //排序
        FieldSortBuilder fieldSortBuilder = new FieldSortBuilder("reservePrice");
        fieldSortBuilder.order(sortOrder);
        nativeSearchQueryBuilder.withSort(fieldSortBuilder);

        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        nativeSearchQueryBuilder.withIndices("ricer_shop_tbk_item");//indexName
        Page<ESTbkItem> shops = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), ESTbkItem.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
                List<ESTbkItem> chunk = Lists.newArrayList();
                if (response.getHits().getHits().length > 0) {
                    for (SearchHit searchHit : response.getHits()) {
                        ESTbkItem item = JSON.parseObject(searchHit.getSourceAsString(), ESTbkItem.class);
                        if (MapUtils.isNotEmpty(searchHit.getHighlightFields())) {
                            HighlightField title = searchHit.getHighlightFields().get("title");
                            if (title != null) {
                                item.setTitle(title.fragments()[0].toString());//替换成高亮的结果
                                System.out.println(title.fragments()[0].toString());
                            }
                        }
                        chunk.add(item);
                    }
                }
                return new AggregatedPageImpl<>((List<T>) chunk, pageable, response.getHits().totalHits);
            }
        });

查询数量的结果就是这样的 ,这样就更加直观看的出,查询的时候名字的哪些词
在这里插入图片描述

扩展

1.有个场景 我查询“打底衫”,ik的分词是 “打底” “衫” ,但是我只想查询关于打底衫的数据, ik也是支持自定义的分词词库的,只需要把我们自定义的分词词库导入到ik插件里面就行了,方法如下:
红红火火恍恍惚惚
在这里插入图片描述
还没深入研究。。。另外查资料了解吧

es也是前段时间项目里面用到了,就自己搭建了了解了一下, 最近需要用到分词, 所以又查各种资料,然后就想着干脆记录一下,免的忘记了,
本人对es也是入门级的, 有错误的的地方,还请见谅,可以指出,我及时修改

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值