一、在构建利用 FunctionScoreQueryBuilder改变某字段值的时候,需要 以"_score"排序,但是查出来的_score分数为0.0或null,主要原因是:查询语句searchQuery里面使用了其它字段作为排序字段,es默认使用score为排序字段,如果使用其它字段作为排序字段,_score则为null,但是还需要注意的是,构建查询条件时,有过滤条件的查询语句{QueryBuilders.boolQuery().filter()},_score分数也会为0.0或null;

// 2.改变算分
    private FunctionScoreQueryBuilder getFunctionScoreQueryBuilder(BoolQueryBuilder boolQuery, String name) {
        return QueryBuilders.functionScoreQuery(
                // 原始查询,相关性算分的查询
                boolQuery,
                // function score的数组
                new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                        // 其中的一个function score 元素
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                // 过滤条件
                                QueryBuilders.termQuery(name, true),
                                // 算分函数
                                ScoreFunctionBuilders.weightFactorFunction(10)
                        )
                });
    }

二、为了避免_score分数为0.0或null,可以在排序条件增加判断条件 ,在没有其他条件的时候默认以_score排序

    //排序
    private SortBuilder getSortBuilder(Param params) {

        if (!StringUtils.isEmpty(params.getLocation())) {
            //按距离排序
            String[] locationStr = params.getLocation().split(",");
            double lon = Double.valueOf(locationStr[1]); //经度
            double lat = Double.valueOf(locationStr[0]); //维度
            GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort("location", new GeoPoint(lat, lon))
                    .unit(DistanceUnit.KILOMETERS)
                    .order(SortOrder.ASC);//排序方式
            //返回
            return geoDistanceSortBuilder;
        }
        //按字段名排序
        else if (!StringUtils.isEmpty(params.getSortBy())) {
            FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort(params.getSortBy());
            return fieldSortBuilder;
        }
        //默认排序 _score
        ScoreSortBuilder scoreSortBuilder = SortBuilders.scoreSort();

        return scoreSortBuilder;
    }

三、构建查询添加时使用 must 或者should, 如果使用了.filter(),_score分数会为0.0或null

 private BoolQueryBuilder getBoolQueryBuilder(Param params) {

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (StringUtils.isEmpty(params.getKey())) {
            //查询所有
            boolQuery.must(QueryBuilders.matchAllQuery());

        } else {
            //设置全文查询
            boolQuery.must(QueryBuilders.multiMatchQuery(params.getKey(), "name", "brand", "city", "address"));
        }
        //设置城市查询
        if (!StringUtils.isEmpty(params.getCity())) {
            boolQuery.must(QueryBuilders.termQuery("city", params.getCity()));//城市
        }
        //设置/品牌查询
        if (!StringUtils.isEmpty(params.getBrand())) {
            boolQuery.must(QueryBuilders.termQuery("brand", params.getBrand()));//品牌
        }
        //设置星级查询
        if (!StringUtils.isEmpty(params.getStarName())) {
            boolQuery.must(QueryBuilders.termQuery("starName", params.getStarName()));//星级
        }
        //设置价格 范围查询
        if (!StringUtils.isEmpty(params.getMinPrice()) && !StringUtils.isEmpty(params.getMaxPrice())) {
            boolQuery.must(
                    QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));//价格
        }

        //设置距离查询;根据经纬度查询 location 经纬度字段,distance 距离中心范围KM,lat  lon 圆心经纬度
        if (!StringUtils.isEmpty(params.getDistance())) {

            //距离
            double lon = 113.90449; //经度
            double lat = 22.57809; //维度
            GeoDistanceQueryBuilder locationBuilder = QueryBuilders.geoDistanceQuery("location")//字段名
                    .distance(Double.valueOf(params.getDistance()), DistanceUnit.KILOMETERS)//半径
                    .point(new GeoPoint(lat, lon));//经纬度坐标
            //添加到查询构建
            boolQuery.must(locationBuilder);
        }

        return boolQuery;
    }

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐