ElasticSearch 9种查询搜索管理

ElasticSearch 9种查询搜索管理

1. 查询所有文档

    //查询所有document
    @Test
    public void testSearch() throws IOException {
        //设置查询索引库和类型
        SearchRequest xc_course = new SearchRequest("xc_course");
        xc_course.types("doc");

        //设置查询范围
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        //要查询的出来的映射和不想要查询出来的映射
        searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "timestamp", "pic"}, new String[]{});

        //索引绑定条件
        xc_course.source(searchSourceBuilder);

        //开始搜素
        SearchResponse searchResponse = restHighLevelClient.search(xc_course);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println("============================================");
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            System.out.println(hitsHit.getId());
            Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
            System.out.println(sourceAsMap.get("name"));
            System.out.println(sourceAsMap.get("description"));
            System.out.println(sourceAsMap.get("studymodel"));
            System.out.println(sourceAsMap.get("price"));
            System.out.println(sourceAsMap.get("timestamp"));
            System.out.println(sourceAsMap.get("pic"));
            System.out.println("=============================================");
        }
    }

2. 分页查询

分页是SearchSourceBuilder的一个功能

//分页查询
    @Test
    public void testPageSearch() throws IOException {
        //设置查询索引库和类型
        SearchRequest xc_course = new SearchRequest("xc_course");
        xc_course.types("doc");

        //设置查询范围
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        //要查询的出来的映射和不想要查询出来的映射
        searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "timestamp", "pic"}, new String[]{});

        //设置分页参数
        int page = 1;
        int size = 1;
        int from = (page - 1) * size;
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);

        //索引绑定条件
        xc_course.source(searchSourceBuilder);

        //开始搜素
        SearchResponse searchResponse = restHighLevelClient.search(xc_course);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println("============================================");
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            System.out.println(hitsHit.getId());
            Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
            System.out.println(sourceAsMap.get("name"));
            System.out.println(sourceAsMap.get("description"));
            System.out.println(sourceAsMap.get("studymodel"));
            System.out.println(sourceAsMap.get("price"));
            System.out.println(sourceAsMap.get("timestamp"));
            System.out.println(sourceAsMap.get("pic"));
            System.out.println("=============================================");
        }
    }

3. Term Query

//查询name为spring的document -- 精准查询 --不再将关键词分词
    @Test
    public void testExectlySearch() throws IOException {
        //设置查询索引库和类型
        SearchRequest xc_course = new SearchRequest("xc_course");
        xc_course.types("doc");

        //设置查询范围
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termQuery("name", "spring"));
        searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "timestamp", "pic"}, new String[]{});

        //索引绑定条件
        xc_course.source(searchSourceBuilder);

        //开始搜素
        SearchResponse searchResponse = restHighLevelClient.search(xc_course);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println("============================================");
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            System.out.println(hitsHit.getId());
            Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
            System.out.println(sourceAsMap.get("name"));
            System.out.println(sourceAsMap.get("description"));
            System.out.println(sourceAsMap.get("studymodel"));
            System.out.println(sourceAsMap.get("price"));
            System.out.println(sourceAsMap.get("timestamp"));
            System.out.println(sourceAsMap.get("pic"));
            System.out.println("=============================================");
        }
    }

根据id精确查询

//根据id查询
    @Test
    public void testIDSearch() throws IOException {
        //设置查询索引库和类型
        SearchRequest xc_course = new SearchRequest("xc_course");
        xc_course.types("doc");

        //设置查询范围
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        String[] ids = {"1", "3"};
        searchSourceBuilder.query(QueryBuilders.termsQuery("_id", ids));
        searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "timestamp", "pic"}, new String[]{});

        //索引绑定条件
        xc_course.source(searchSourceBuilder);

        //开始搜素
        SearchResponse searchResponse = restHighLevelClient.search(xc_course);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println("============================================");
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            System.out.println(hitsHit.getId());
            Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
            System.out.println(sourceAsMap.get("name"));
            System.out.println(sourceAsMap.get("description"));
            System.out.println(sourceAsMap.get("studymodel"));
            System.out.println(sourceAsMap.get("price"));
            System.out.println(sourceAsMap.get("timestamp"));
            System.out.println(sourceAsMap.get("pic"));
            System.out.println("=============================================");
        }
    }

4. match Query

match Query即全文检索,它的搜索方式是先将搜索字符串分词,再使用各各词条从索引中搜索。 match query与Term query区别是match query在搜索前先将搜索关键字分词,再拿各各词语去索引中搜索。

4.1 基础使用

operator:or 表示 只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。

 //matchQuery 基础使用
    @Test
    public void testMatchSearch01() throws IOException {
        //设置查询索引库和类型
        SearchRequest xc_course = new SearchRequest("xc_course");
        xc_course.types("doc");

        //设置查询范围
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders
                .matchQuery("name", "spring开发")
                .operator(Operator.AND));//operation可以是AND或者OR,根据字面理解
        searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "timestamp", "pic"}, new String[]{});

        //索引绑定条件
        xc_course.source(searchSourceBuilder);

        //开始搜素
        SearchResponse searchResponse = restHighLevelClient.search(xc_course);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println("============================================");
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            System.out.println(hitsHit.getId());
            Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
            System.out.println(sourceAsMap.get("name"));
            System.out.println(sourceAsMap.get("description"));
            System.out.println(sourceAsMap.get("studymodel"));
            System.out.println(sourceAsMap.get("price"));
            System.out.println(sourceAsMap.get("timestamp"));
            System.out.println(sourceAsMap.get("pic"));
            System.out.println("=============================================");
        }
    }

4.2 minimum_should_match

上边使用的operator = or表示只要有一个词匹配上就得分,如果实现三个词至少有两个词匹配如何实现?
使用minimum_should_match可以指定文档匹配词的占比。

//matchQuery minimum_should_match
    @Test
    public void testMatchSearch02() throws IOException {
        //设置查询索引库和类型
        SearchRequest xc_course = new SearchRequest("xc_course");
        xc_course.types("doc");

        //设置查询范围
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders
                .matchQuery("description", "前台页面开发框架构")
                .minimumShouldMatch("40%"));
        searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "timestamp", "pic"}, new String[]{});

        //索引绑定条件
        xc_course.source(searchSourceBuilder);

        //开始搜素
        SearchResponse searchResponse = restHighLevelClient.search(xc_course);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println("============================================");
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            System.out.println(hitsHit.getId());
            Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
            System.out.println(sourceAsMap.get("name"));
            System.out.println(sourceAsMap.get("description"));
            System.out.println(sourceAsMap.get("studymodel"));
            System.out.println(sourceAsMap.get("price"));
            System.out.println(sourceAsMap.get("timestamp"));
            System.out.println(sourceAsMap.get("pic"));
            System.out.println("=============================================");
        }
    }

5. multi Query

上边学习的termQuery和matchQuery一次只能匹配一个Field,本节学习multiQuery,一次可以匹配多个字段。

5.1 基础使用,并提高field的权重boost倍

单项匹配是在一个field中去匹配,多项匹配是拿关键字去多个Field中匹配。

//查询多个域
    @Test
    public void testMultiSearch() throws IOException {
        //设置查询索引库和类型
        SearchRequest xc_course = new SearchRequest("xc_course");
        xc_course.types("doc");

        //设置查询范围
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders
                .multiMatchQuery("spring css", "name", "description")//之前的Query构造方法都是字段名在前面,multiMatchQuery是字段名在后面
                .minimumShouldMatch("50%")
                .field("name", 10));//这里是将name这个字段的相关度(权重)提高10倍
        searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "timestamp", "pic"}, new String[]{});

        //索引绑定条件
        xc_course.source(searchSourceBuilder);

        //开始搜素
        SearchResponse searchResponse = restHighLevelClient.search(xc_course);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println("============================================");
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            System.out.println(hitsHit.getId());
            System.out.println(hitsHit.getScore());
            Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
            System.out.println(sourceAsMap.get("name"));
            System.out.println(sourceAsMap.get("description"));
            System.out.println(sourceAsMap.get("studymodel"));
            System.out.println(sourceAsMap.get("price"));
            System.out.println(sourceAsMap.get("timestamp"));
            System.out.println(sourceAsMap.get("pic"));
            System.out.println("=============================================");
        }
    }

6. 布尔查询

布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。

must:表示必须,多个查询条件必须都满足。(通常使用must)

should:表示或者,多个查询条件只要有一个满足即可。

must_not:表示非。

//多种查询条件查询所有document
    @Test
    public void testMustSearch() throws IOException {
        //设置查询索引库和类型
        SearchRequest xc_course = new SearchRequest("xc_course");
        xc_course.types("doc");

        //设置查询范围
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders
                .multiMatchQuery("spring css", "name", "description")
                .minimumShouldMatch("50%")
                .field("name", 10);
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("studymodel", "201001");
        boolQuery.must(multiMatchQueryBuilder).must(termQueryBuilder);
        searchSourceBuilder.query(boolQuery);
        searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "timestamp", "pic"}, new String[]{});

        //索引绑定条件
        xc_course.source(searchSourceBuilder);

        //开始搜素
        SearchResponse searchResponse = restHighLevelClient.search(xc_course);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println("============================================");
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            System.out.println(hitsHit.getId());
            Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
            System.out.println(sourceAsMap.get("name"));
            System.out.println(sourceAsMap.get("description"));
            System.out.println(sourceAsMap.get("studymodel"));
            System.out.println(sourceAsMap.get("price"));
            System.out.println(sourceAsMap.get("timestamp"));
            System.out.println(sourceAsMap.get("pic"));
            System.out.println("=============================================");
        }
    }

7. 过滤器

过虑是针对搜索的结果进行过虑,过虑器主要判断的是文档是否匹配,不去计算和判断文档的匹配度得分,所以过虑器性能比查询要高,且方便缓存,推荐尽量使用过虑器去实现查询或者过虑器和查询共同使用。

过滤器的配置是在boolQueryBuilder配置

        //过滤器
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100));
        searchSourceBuilder.query(boolQueryBuilder);

8. 排序

排序是SearchSourceBuilder的一个功能

	//排序
        searchSourceBuilder.sort("price", SortOrder.DESC);

9. 高亮显示

高亮显示可以将搜索结果一个或多个字突出显示,以便向用户展示匹配关键字的位置。 在搜索语句中添加highlight即可实现

 //运用所有查询方式
    @Test
    public void testFilterSearch() throws IOException {
        //设置查询索引库和类型
        SearchRequest xc_course = new SearchRequest("xc_course");
        xc_course.types("doc");

        //设置查询范围
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //查询所有
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "开发");
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(matchQueryBuilder);
        //过滤器
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100));
        searchSourceBuilder.query(boolQueryBuilder);
        //排序
        searchSourceBuilder.sort("price", SortOrder.DESC);
        searchSourceBuilder.fetchSource(new String[]{"name", "studymodel", "price", "timestamp", "pic"}, new String[]{});
        //高亮显示
        HighlightBuilder highlightBuilder=new HighlightBuilder();
        highlightBuilder.preTags("<tag>");
        highlightBuilder.postTags("</tag>");
        highlightBuilder.fields().add(new HighlightBuilder.Field("name"));

        searchSourceBuilder.highlighter(highlightBuilder);

        //索引绑定条件
        xc_course.source(searchSourceBuilder);

        //开始搜素
        SearchResponse searchResponse = restHighLevelClient.search(xc_course);
        SearchHits hits = searchResponse.getHits();
        System.out.println("一共有"+hits.getTotalHits()+"条记录");
        System.out.println("============================================");
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            System.out.println("document的id:"+hitsHit.getId());
            Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
            System.out.println("原本的name:"+sourceAsMap.get("name"));
            Map<String, HighlightField> highlightFields = hitsHit.getHighlightFields();
            if(highlightFields!=null||highlightFields.size()!=0){
                HighlightField highlightField = highlightFields.get("name");
                if(highlightField!=null){
                    Text[] fragments = highlightField.getFragments();
                    StringBuilder stringBuilder=new StringBuilder();
                    for (Text text : fragments) {
                        stringBuilder.append(text);
                    }
                    System.out.println("高亮显示的name:"+stringBuilder.toString());
                }
            }
            System.out.println(sourceAsMap.get("description"));
            System.out.println(sourceAsMap.get("studymodel"));
            System.out.println(sourceAsMap.get("price"));
            System.out.println(sourceAsMap.get("timestamp"));
            System.out.println(sourceAsMap.get("pic"));
            System.out.println("=============================================");
        }
    }

转载于:https://my.oschina.net/edisonOnCall/blog/3043250

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/100950.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号