ES QueryBuilder学习

    public void test() throws IOException {
        # 创建一个Search 对象
        SearchRequest searchRequest = new SearchRequest();
   
        # 创建一个Builder 对象 对条件进行封装
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        # 查询条件: 字段名为text  内容含有19的数据
        searchSourceBuilder.query(QueryBuilders.matchQuery("text", "19"));
        # 查询条件: 在上面条件的基础上 加上字段 jiage 内容含有329的数据
        searchSourceBuilder.query(QueryBuilders.matchQuery("jiage", "329"));

        # 从搜索结果中取第0条开始的10条数据,数据量最多不要超过10000 会报错,有解决方案百度
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(10);

        # 排序根据字段id 按照正序排列
        searchSourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.ASC));

        searchSourceBuilder.fetchSource(false);

        # 参数,用于是否需要过滤
        String[] includeFields = new String[]{"id", "dizhi","text","jiage"};
        # 第1个参数是 需要显示的字段,第2个参数是需要过滤的字段
        searchSourceBuilder.fetchSource(includeFields, null);

        # 进行构建 
        searchRequest.source(searchSourceBuilder);
        searchRequest.scroll(TimeValue.timeValueMinutes(1L));

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        # 获取数据 数据可以是多种类型的
        SearchHits hits = searchResponse.getHits();
        SearchHit[] hits1 = hits.getHits();

        List list = new ArrayList();
        for (SearchHit hit : hits1) {
            list.add(hit.getSourceAsString());
        }
        System.out.println(list);
    }
}

        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
        // 结果的Index
            String index = hit.getIndex();
        // 结果的type
            String type = hit.getType();
        // 结果的ID
            String id = hit.getId();
        // 结果的评分
            float score = hit.getScore();
        // 查询的结果 JSON字符串形式
            String sourceAsString = hit.getSourceAsString();
        // 查询的结果 Map的形式
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
        // Document的title
            String documentTitle = (String) sourceAsMap.get("title");
        // 结果中的某个List
            List<Object> users = (List<Object>) sourceAsMap.get("user");
        // 结果中的某个Map
            Map<String, Object> innerObject = (Map<String, Object>)sourceAsMap.get("innerObject");
        }

 

QueryBuilder  常用来配合 Search 查询来使用 

boolQuery() 布尔查询,可以用来组合多个查询条件 
fuzzyQuery() 相似度查询 
matchAllQuery() 查询所有数据 
regexpQuery() 正则表达式查询 
termQuery() 词条查询 
wildcardQuery() 模糊查询 
等等.....

1.matchQuery 匹配查询: 


    matchQuery可以简单理解为mysql中的like,但是我不知道我这么理解对不对,因为在elasticsearch中使用matchQuery查询时,他会对查询的field进行分词,打个比方,我们搜索"联想笔记本电脑",他可能会将他拆分为:“联想”,“电脑”,“联想电脑”,那么如果一个filed中包括 联想 两个字就可以被搜出来。当然我们进行查询的这个field的mapping必须是text类型。(如果是中文分词的话,还需要配置中文分词器),他的查询语句和上边基本相似

public void test() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        # matchQuery 匹配查询
        searchSourceBuilder.query(QueryBuilders.matchQuery("text", "19"));


    # multiMatchQuery(Object text, String... fieldNames) 多个字段匹配某一个值
    # 搜索name中或interest中包含有music的文档 (必须与music一致)
    public void test() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        searchSourceBuilder.query(QueryBuilders.multiMatchQuery("music", "name", "interest"));
}



    # wildcardQuery()模糊查询,?匹配单个字符,*匹配多个字符
    # 搜索名字中含有jack文档 (name中只要包含jack即可)
    public void test() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        searchSourceBuilder.query(QueryBuilders.wildcardQuery("name","*jack?*"));
}

2.matchAllQuery 查询所用

查询指定index和type中的所用记录,相当于sql:select * from sales 

    public void test() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
}

3.termQuery等值搜索

我们在数据库中进行查询的时候,sql:select sales from tvs where brand = ‘小米’,那么在elasticsearch中的javaapi怎么写呢?这里我们用到一个termQuery,他相当于sql语句中的“=”,使用这个搜索一般是对索引中keyword的mapping进行等值搜索      term query 属于过滤器查询,可以处理数字(numbers)、布尔值(Booleans)、日期(dates)以及文本(text)。

    public void test() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termQuery("name", "张三"));
}


    # terms 是多值判断

    public void test() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termsQuery("name", "张三", "李四", "王五"));
}

4.matchPhraseQuery短语搜索

理解:   你会发现,使用“小别克老”没有查询出任何结果,而使用“小别克听”则查询出了我们需要的结果,这便matchPhraseQuery和matchQuery等的区别,在使用matchQuery等时,即使你传入的是“小别克老”,在执行查询时,“小别克老”会被分词器分词,例如paoding解析成“小别/别克/老”,而使用matchPhraseQuery时,“小别克老”并不会被分词器分词,而是直接以一个短语的形式查询,而如果你在创建索引所使用的field的value中没有这么一个短语(顺序无差,且连接在一起),那么将查询不出任何结果。

    public void test() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchPhraseQuery("name", "张三"));
}

5.prefixQuery前缀搜索

如我我们需要查询的title中有“大话西游电影”,“大话西游小说”,使用prefixQuery查询“大话西游”,那么那两条数据就会出来

    public void test() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.prefixQuery("title", "大话西游"));
}

6.disMaxQuery


disMaxQuery适用于多个field的进行搜索,我们在多个field搜索时候,可能会遇到多个field匹配到了更多的词会在前面,而一个field匹配了更多的词就会排名靠后。disMax就是解决这个问题,dismax使搜索到的结果,应该是某一个field中匹配到了尽可能多的关键词,被排在前面;而不是尽可能多的field匹配到了少数的关键词,排在了前面

    public void test() throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = newSearchSourceBuilder();  
searchSourceBuilder.query(QueryBuilders.disMaxQuery().add(QueryBuilders.matchQuery("name", "张三")));
}

7.boolQuery 组合查询条件

boolQuery用来将搜索的条件进行组合,即将多个组合条件组合在一起,常用的几种组合方式有must、should、mustNot,我们拿下面对应的sql语句举例子

# sql:select * from sales where brand = '小米' and color='红色',通过bool将两个查询条件组合,
# must相当于sql中的= 必须匹配的意思
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
		boolQuery.must(QueryBuilders.termQuery("brand", "小米"))
				.must(QueryBuilders.termQuery("color", "红色"));

# sql:select * from sales where brand = '小米' or color='红色';使用should相当于sql语句中的or
BoolQueryBuilder boolQuery2 = QueryBuilders.boolQuery();
		boolQuery2.should(QueryBuilders.termQuery("brand", "小米"))
				.should(QueryBuilders.termQuery("color", "红色"));

# sql:select * from sales where brand = '小米' and color != '红色' mustNot相当于!= 必须不匹配
BoolQueryBuilder boolQuery3 = QueryBuilders.boolQuery();
		boolQuery2.must(QueryBuilders.termQuery("brand", "小米"))
				.mustNot(QueryBuilders.termQuery("color", "红色"));

# sql:select * from sales where (brand = '小米' or color = '红色') and brand != '长虹'
BoolQueryBuilder boolQuery4 = QueryBuilders.boolQuery();
		BoolQueryBuilder boolQuery5 = QueryBuilders.boolQuery();
		boolQuery5.should(QueryBuilders.termQuery("brand", "小米"))
				.should(QueryBuilders.termQuery("color", "红色"));
		boolQuery4.must(boolQuery5)
				.mustNot(QueryBuilders.termQuery("brand", "长虹"));




//设置查询条件
        
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (StringUtils.isNotEmpty(text)) {
            //查询条件:字段名为text,内容含有text的数据
            boolQuery.must(QueryBuilders.matchQuery("text", text));
        }
        if (StringUtils.isNotEmpty(keywords)) {
            //查询条件:字段名为keywords,内容含有keywords的数据
            boolQuery.must(QueryBuilders.matchQuery("keywords", keywords));
        }
        if (StringUtils.isNotEmpty(topic)) {
            //查询条件:字段名为topic,内容含有topic的数据
            boolQuery.must(QueryBuilders.matchQuery("topic", topic));
        }

8.rangeQuery属于过滤器查询

是范围查询,有时候,范围查询比精确值查询更有用,比如我想知道价格在20到40之间的商品;

range query可以处理数字(numbers)、日期(dates)以及字符串,不过字符串还是不要用范围查询的好,效率会很低;

对数字取范围没啥好说的, 就大于、大于等于、小于、小于等于四个符号加数字就可以;

# 闭区间查询
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").from(${fieldValue1}).to(${fieldValue2});

# 开区间查询
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").from(${fieldValue1}, false).to(${fieldValue2}, false);

# 大于
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").gt(${fieldValue});

#大于等于
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").gte(${fieldValue});

# 小于
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").lt(${fieldValue});

# 小于等于
QueryBuilder qb1 = QueryBuilders.rangeQuery("${fieldName}").lte(${fieldValue});

# 多条件案例
QueryBuilder qb1 = QueryBuilders.moreLikeThisQuery(new String[]{"${fieldName1}"}, new String[]{"${fieldValue1}"}, null);
QueryBuilder qb2 = QueryBuilders.rangeQuery("${fieldName2}").gt("${fieldValue2}");
QueryBuilder qb3 = QueryBuilders.boolQuery().must(qb1).must(qb2);

官网介绍:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-query-builders.html
 

  • 24
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
对于学习Elasticsearch,你可以按照以下步骤进行: 1. 首先,你可以从Docker Hub上获取Elasticsearch的镜像。你可以使用以下命令来拉取特定版本的Elasticsearch镜像: ``` docker pull docker.elastic.co/elasticsearch/elasticsearch:7.6.2 ``` 2. 接下来,你可以创建一个简单的Dockerfile来构建一个Elasticsearch容器。Dockerfile的内容可以参考以下示例: ``` FROM docker.elastic.co/elasticsearch/elasticsearch:7.6.2 COPY --chown=elasticsearch:elasticsearch elasticsearch.yml /usr/share/elasticsearch/config/ ``` 这个Dockerfile会将你的自定义配置文件`elasticsearch.yml`复制到Elasticsearch容***-analysis-ik`项目。该项目提供了一个支持中文分词的插件,你可以在以下链接找到它: ``` https://github.com/medcl/elasticsearch-analysis-ik ``` 你可以根据项目的文档和示例,自定义和配置分词器和分析器以满足你的需求。 通过上述步骤,你可以开始学习和使用Elasticsearch,并根据需要进行自定义配置和扩展。希望对你有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [ES(Elasticsearch)入门学习教程](https://blog.csdn.net/m0_55070913/article/details/124243790)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [ElasticSearch学习总结(基础篇,可学习,可复习)](https://blog.csdn.net/Gaowumao/article/details/124484971)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值