全文检索 Elasticearch

官方网址:https://www.elastic.co/cn/products/elasticsearch

Githubhttps://github.com/elastic/elasticsearch

优点

1.扩展性好,可部署上百台服务器集群,处理PB级数据。

2.近实时的去索引数据、搜索数据。

essolr选择哪个?

1.如果你公司现在用的solr可以满足需求就不要换了。

2.如果你公司准备进行全文检索项目的开发,建议优先考虑elasticsearch,因为像Github这样大规模的搜索都在用它。

ElasticSearch原理

es在项目中的应用方式:

1)用户在前端搜索关键字

2)项目前端通过http方式请求项目服务端

3)项目服务端通过Http RESTful方式请求ES集群进行搜索

4ES集群从索引库检索数据。

RestHighLevelClient介绍

RestHighLevelClient是Elasticsearch官方提供的Java高级REST客户端,它基于Java Low Level REST Client,提供了更多的接口和功能。相比于低级别客户端,RestHighLevelClient更加易用和灵活,可以更方便地进行索引、搜索、聚合等操作。同时,它也支持异步操作和连接池等特性,可以提高客户端的性能和稳定性。需要注意的是,RestHighLevelClient的版本需要与Elasticsearch集群的版本保持一致。

el架包

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>6.2.1</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>6.2.1</version>
</dependency>

el配置

@Configuration
public class EsConfig {

    //也可以使用application.yml文件来配置当前主机和端口
    
    //那就要声明主机和端口属性
    //使用注解value来获取yml文件中的主机和端口
    @Value("${es.port}")
    private String port;

    @Value("${es.host}")
    private String host;

    @Bean
    public RestHighLevelClient client() {
        HttpHost httpHost = new HttpHost("127.0.0.1", 9200, "http");
        return new RestHighLevelClient(RestClient.builder(httpHost));
    }
}

使用java代码创建索引库

@Override
    public void crateIndex() throws Exception {

        //声明高级rest客户端
        @Autowired
        private RestHighLevelClient client;
           
        //创建索引请求对象,声明索引名
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("tb_sku");
        //创建索引的分片数量,副本数量
        createIndexRequest.settings(Settings.builder()
                                                   .put("number_of_shards","1")
                                                   .put("number_of_replicas", "0"));
        //设置你需要的列的映射
        createIndexRequest.mapping("doc", "${...}", XContentType.JSON);
        CreateIndexResponse response = client.indices()    
                                       .create(createIndexRequest, RequestOptions.DEFAULT);
        System.out.println(response.isAcknowledged());

    }

使用搜索引擎进行分页查询

    //分页查询
    public Page<Course> page(Integer index, Integer size) throws Exception{
        //查询请求对象
        SearchRequest searchRequest = new SearchRequest("xc_course");
        searchRequest.types("doc");
        //查询构建,设置查询方法(全部查询,分页查询,条件查询)
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置分页参数
        searchSourceBuilder.from((index - 1) * size);
        searchSourceBuilder.size(size);
        //设置全部查询
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        //过滤显示的列
        searchSourceBuilder.fetchSource(new String[]            
                             {"name","description","studymodel","price"},new String[]{});
        //查询构建存储到请求对象中
        searchRequest.source(searchSourceBuilder);
        //执行请求并获取响应
        SearchResponse searchResponse = client.search(searchRequest, 
                                                      RequestOptions.DEFAULT);
        //获取最外层
        SearchHits hits = searchResponse.getHits();
        Long totalHits = hits.getTotalHits();
        System.out.println("总记录数:" + totalHits);
        //获取用户数据
        SearchHit[] searchHits = hits.getHits();
        List<Course> list = new ArrayList<>();
        for (SearchHit hit : searchHits) {
            String id = hit.getId();
            String json = hit.getSourceAsString();
            Course course = JSON.parseObject(json, Course.class);
            course.setId(id);
            list.add(course);
        }
        Page<Course> page = new Page<>();
        page.setIndex(index);
        page.setSize(size);
        page.setCount(totalHits.intValue());
        page.setData(list);
        return page;
    }

多条件内容查询

/**
     * 多条件内容查询
     * @param keyword
     * @param studymodel
     * @param min
     * @param max
     * @throws Exception
     */
    public void filter(String keyword,String studymodel, Double min, Double max) throws Exception{
        SearchRequest searchRequest = new SearchRequest("xc_course");
        searchRequest.types("doc");
        //查询资源构建
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //创建组合查询对象
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //分词查询
        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, "name", "description");
        multiMatchQueryBuilder.field("name",10);
        boolQuery.must(multiMatchQueryBuilder);

        //精准查
        if(!StringUtils.isEmpty(studymodel)){
            TermQueryBuilder termQuery = QueryBuilders.termQuery("studymodel", studymodel);
            //组合条件
            boolQuery.filter(termQuery);
        }

        if(!ObjectUtils.isEmpty(min) && !ObjectUtils.isEmpty(max)){
            RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("price");
            rangeQuery.gte(min).lte(max);
            //添加范围查询
            boolQuery.filter(rangeQuery);
        }

        //添加排序
        searchSourceBuilder.sort(new FieldSortBuilder("studymodel").order(SortOrder.DESC));
        searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.ASC));

        //创建高亮对象
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<span style='color:red;'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
        highlightBuilder.fields().add(new HighlightBuilder.Field("description"));
        searchSourceBuilder.highlighter(highlightBuilder);

        //设置查询构建
        searchSourceBuilder.query(boolQuery);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit searchHit : searchHits) {
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            //所有的高亮对象
            Map<String, HighlightField> mapField = searchHit.getHighlightFields();
            //获取name高亮数据
            HighlightField nameField = mapField.get("name");
            if(!ObjectUtils.isEmpty(nameField)){
                Text[] nameText = nameField.fragments();
                StringBuffer namebuf = new StringBuffer();
                for (Text text : nameText) {
                    namebuf.append(text.toString());
                }
                sourceAsMap.put("name",namebuf.toString());
            }

            //获取description高亮数据
            HighlightField descriptionField = mapField.get("description");
            if(!ObjectUtils.isEmpty(descriptionField)){
                Text[] descriptionText = descriptionField.fragments();
                StringBuffer descriptionbuf = new StringBuffer();
                for (Text text : descriptionText) {
                    descriptionbuf.append(text.toString());
                }
                sourceAsMap.put("description",descriptionbuf.toString());
            }
            System.out.println(sourceAsMap);
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值