当前位置 博文首页 > RemainderTime:防踩坑日记(一)(ES)elasticsearch中的对象Qu

    RemainderTime:防踩坑日记(一)(ES)elasticsearch中的对象Qu

    作者:[db:作者] 时间:2021-07-12 21:43

    我正在参加《新程序员》CSDN有奖征文
    地址:https://marketing.csdn.net/p/52c37904f6e1b69dc392234fff425442

    在开发项目中给定一个字段指定的一组值,需要从es库中通过这个字段查询满足这一组值任何一个对象集合(相当于达到mysql中关键字 in 的查询效果),同时还需要满足其他字段的查询条件。

    错误代码
    • 下述中用用到的api方法 .should() 相当于 or, .must() 相当于 and
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    
    ...
    
    List<Integer> list = Arrays.asList(25,256,155);
    //查询满足list集合任意一个条件的数据
    BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    list.forEach(x->{                    
      queryBuilder.should(QueryBuilders.termQuery("id.keyword",x));
                 });
    //查询同时满足一下条件的数据
    queryBuilder.must(QueryBuilders.termsQuery("goodsClassId","5469464641646"));
    queryBuilder.must(QueryBuilders.termsQuery("goodsName","野草"));
    //查询
    elasticsearchTemplate.sreach(queryBuilder ,EsGoodsData.class)                    
    
    
    • 查询结果 使用 .should()方法的条件未生效,只查询出了使用满足 .must()方法的数据
    失效原因
    • should在和must同时使用的时候es内部属性 minumum_should_match 默认是 0
    • 单独使用should时 minumum_should_match 默认是 1
    解决方案
    1. 方案一:为minumum_should_match 手动设值
    //代码承接上述错误代码,新增下面一行
    boolQueryBuilder.minimumShouldMatch(1);
    
    1. 方案二:将should查询对象设置到must方法中
    //主查询对象
    BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    List<Integer> list = Arrays.asList(25,256,155);
    //should查询对象
    BoolQueryBuilder shouldQ= QueryBuilders.boolQuery();
    list.forEach(x->{                    
      shouldQ.should(QueryBuilders.termQuery("id.keyword",x));
                 });
    //将should查询对象设置到 must 方法中         
    queryBuilder.must(shouldQ)
    queryBuilder.must(QueryBuilders.termsQuery("goodsClassId","5469464641646"));
    queryBuilder.must(QueryBuilders.termsQuery("goodsName","野草"));
    //查询
    elasticsearchTemplate.sreach(queryBuilder ,EsGoodsData.class)  
    

    疑惑与思考
    1. minumum_should_match的作用是什么?

    作用: minimum_should_match用于控制bool中should列表,至少匹配几个条件才召回doc。
    多种情况: 默认不传minimum_should_match的情况下,查询分2个情况:

    • 当bool处在query上下文中时,如果使用了must或者filter匹配了doc,那么should即便一条都不满足也可以召回doc(上述产生查询失效的原因)。
    • 当bool处在父bool的filter/must上下文中时(就是上述的解决方案2), 或者 bool处在query上下文且没有must/filter子句的时候,should至少匹配1个才能召回doc。
    1. 为什么should与must/filter同时使用会使 minumum_should_match 默认值 为 0呢?
      目前还没有找到原因,希望知道的多多留言告诉我,我补充上去

    cs