elasticseacth基础操作--QueryBuilders的使用

elasticseacth基础操作--QueryBuilders的使用

1. 基本查询

  • QueryBuilders.matchQuery() 会根据分词器进行分词,分词之后去查询

  • QueryBuilders.termQuery() 不会进行分词,且完全等于才会匹配

    QueryBuilders.termQuery("name","v1");
    
  • QueryBuilders.termsQuery() 一个字段匹配多个值,where name = ‘A’ or name = ‘B’

    QueryBuilders.termsQuery("name","v1","v2","v3");
    
  • QueryBuilders.multiMatchQuery() 会分词 一个值对应多个字段 where username = ‘zs’ or password = ‘zs’

  • QueryBuilders.matchPhraseQuery() 不会分词,当成一个整体去匹配,相当于 %like%

  • 如果想使用一个字段匹配多个值,并且这多个值是and关系,如下 要求查询的数据中必须包含北京‘和’天津QueryBuilders.matchQuery(“address”,“北京 天津”).operator(Operator.AND)

  • 如果想使用一个字段匹配多个值,并且这多个值是or关系,如下 要求查询的数据中必须包含北京‘或’天津

  • QueryBuilders.matchQuery(“address”,“北京 天津”).operator(Operator.OR)

    mathcQuery与termQuery区别:

    **matchQuery:会将搜索词分词,再与目标查询字段进行匹配,若分词中的任意一个词与目标字段匹配上,则可查询到。

    termQuery:不会对搜索词进行分词处理,而是作为一个整体与目标字段进行匹配,若完全匹配,则可查询到==

2. 复合查询

通常都是将多个查询条件组合在一起,常用的有must、must_not、should

  • 测试数据
    有这样一段测试数据

     	 {"address":"鸿星尔克0","codes":"中国人民银行0","id":0,"name":"平安富士康0"}
    	 {"address":"鸿星尔克1","codes":"中国人民银行1","id":1,"name":"平安富士康1"}
    	 {"address":"鸿星尔克2","codes":"中国人民银行2","id":2,"name":"平安富士康2"}
    	 {"address":"鸿星尔克3","codes":"中国人民银行3","id":3,"name":"平安富士康3"}
    	 {"address":"鸿星尔克4","codes":"中国人民银行4","id":4,"name":"平安富士康4"}
    	 {"address":"汽车家族0","id":0,"name":"快递收货0"}
    	 {"address":"汽车家族1","id":1,"name":"快递收货1"}
    	 {"address":"汽车家族2","id":2,"name":"快递收货2"}
    	 {"address":"汽车家族3","id":3,"name":"快递收货3"}
    	 {"address":"汽车家族4","id":4,"name":"快递收货4"}
    	 {"address":"新鲜水果-徐鲸鱼0","id":0,"name":"东方不败0"}
    	 {"address":"新鲜水果-徐鲸鱼1","id":1,"name":"东方不败1"}
    	 {"address":"新鲜水果-徐鲸鱼2","id":2,"name":"东方不败2"}
    	 {"address":"新鲜水果-徐鲸鱼3","id":3,"name":"东方不败3"}
    	 {"address":"新鲜水果-徐鲸鱼4","id":4,"name":"东方不败4"}
    
    
  • 查询1:查询address 必须包含’汽车’ 或者’水果’的,查询id必须不能包含’2’和’0’的。
    此时需要构造两个条件,类似mysql中的 where (address like %汽车% or
    address like %水果% ) and (id != 1 or id != 2)

    	@Test
    	public void testBoolQuery() throws IOException {
    		SearchRequest searchRequest = new SearchRequest(indexName);
    		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    
    		BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    		boolQuery.must(QueryBuilders.matchQuery("address","水果 汽车").operator(Operator.OR));
    		boolQuery.mustNot(QueryBuilders.termsQuery("id","0","2"));
    		searchSourceBuilder.query(boolQuery);
    
    		searchRequest.source(searchSourceBuilder);
    
    		SearchResponse search = client.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
    		for (SearchHit documentFields : search.getHits().getHits()) {
    			System.out.println(documentFields.getScore() + ":::"  +documentFields.getSourceAsString());
    		}
    	}
    
  • 結果

    image-20221031185635523

  • 查询2:查询address 必须包含’汽车’ 或者’水果’的,查询id必须不能包含’2’和’0’的。name最好是包含 '东方’的。这个最好包含是有最好,没有也无所谓,此时需要用should来封装。

    	@Test
    	public void testBoolQuery() throws IOException {
    		SearchRequest searchRequest = new SearchRequest(indexName);
    		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    
    		BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    		boolQuery.must(QueryBuilders.matchQuery("address","水果 汽车").operator(Operator.OR));
    		boolQuery.mustNot(QueryBuilders.termsQuery("id","0","2"));
    		boolQuery.should(QueryBuilders.matchQuery("name","东方"));
    		searchSourceBuilder.query(boolQuery);
    		
    		searchRequest.source(searchSourceBuilder);
    
    		SearchResponse search = client.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
    		for (SearchHit documentFields : search.getHits().getHits()) {
    			System.out.println(documentFields.getScore() + ":::"  +documentFields.getSourceAsString());
    		}
    	}
    

    image-20221031185756940

  • 复合查询嵌套

    boolQuery.must(QueryBuilders.matchQuery("address","水果 汽车").operator(Operator.OR));
    

    在复合查询时,我们使用must构建了 address必须包含‘汽车’或‘水果’的查询条件,但我们也可以给这个must再嵌套一个布尔查询,这个bool查询应该是一个should关系,如下

    	private BoolQueryBuilder buildBoolQuery(){
    		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    		boolQueryBuilder.should(QueryBuilders.matchQuery("address","水果"));
    		boolQueryBuilder.should(QueryBuilders.matchQuery("address","汽车"));
    		return boolQueryBuilder;
    	}
    
  • 根据id查找

    QueryBuilders.idsQuery(String ..type).ids(Collectionids);

    QueryBuilders.idsQuery().ids("CHszwWRURyK08j01p0Mmug", "ojGrYKMEQCCPvh75lHJm3A");
    
  • 范围查找

    QueryBuilder queryBuilder = QueryBuilders.rangeQuery("user")
          .from("kim")
          .to("lucy")
          .includeLower(true) //包含上界
          .includeUpper(true); //包含下届
    
  • 通配符查找(支持* 匹配任何字符序列,包括空 避免*开始,会检索大量内容造成效率缓慢)

    QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("user","he*o");
    
  • 分词模糊查询 fuzzy query

    QueryBuilders.fuzzyQuery("name","hello");
    
  • 前缀匹配查询 prefix query

    QueryBuilders.prefixQuery("name","hello");
    
  • 嵌套查询

    QueryBuilders.nestedQuery("policy", //path
                QueryBuilders.boolQuery()   // Your query
                    .must(QueryBuilders.termQuery("name", "hello"))
                    .must(QueryBuilders.rangeQuery("age").lt("23"))
                ,ScoreMode.None);// max,total,avg,none
    public static NestedQueryBuilder nestedQuery(String path, QueryBuilder query, ScoreMode scoreMode) {
        return new NestedQueryBuilder(path, query, scoreMode);
    

posted @ 2022-10-31 19:08  a-tao必须奥利给  阅读(2277)  评论(0编辑  收藏  举报