请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

第三题,参考官方文档写的

老师我在看官方文档的时候看到脚本好像分为store,和我们这种,官方好像建议有乘法的先存一下再调用,我们这种是ES内置的吗?不需要先存下吧。

 @Override
    public Map<String, Object> searchES(BigDecimal longitude, BigDecimal latitude, String keyword, Integer orderBy, Integer categoryId, String tags) {

        Map<String, Object> result = new HashMap<>(16);

        SearchRequest searchRequest = new SearchRequest("shop");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //function_score

        //1.1、构建bool query
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("seller_disabled_flag", 0));
        //关键字
        if (StrUtil.isNotEmpty(keyword)) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("name", keyword).boost(0.1f));
        }
        if (null != categoryId) {
            boolQueryBuilder.must(QueryBuilders.termQuery("category_id", categoryId));
        }
        if (StrUtil.isNotEmpty(tags)) {
            boolQueryBuilder.must(QueryBuilders.termQuery("tags", tags));
        }
        //默认排序
        if (null == orderBy) {
            FunctionScoreQueryBuilder.FilterFunctionBuilder[] filterFunctionBuilders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[3];
            //2.1、构建高斯函数
            String origin = longitude + "," + latitude;
            ScoreFunctionBuilder<GaussDecayFunctionBuilder> gaussDecayFunctionBuilder = new GaussDecayFunctionBuilder("location", origin, "100km", "0km", 0.5);
            gaussDecayFunctionBuilder.setWeight(9);
            filterFunctionBuilders[0] = new FunctionScoreQueryBuilder.FilterFunctionBuilder(gaussDecayFunctionBuilder);
            //2.2、构建自定义的remark_score
            ScoreFunctionBuilder<FieldValueFactorFunctionBuilder> remarkScoreFunctionBuilder = new FieldValueFactorFunctionBuilder("remark_score");
            remarkScoreFunctionBuilder.setWeight(0.2f);
            filterFunctionBuilders[1] = new FunctionScoreQueryBuilder.FilterFunctionBuilder(remarkScoreFunctionBuilder);
            //2.3、构建自定义的seller_remark_score
            ScoreFunctionBuilder<FieldValueFactorFunctionBuilder> sellerRemarkScoreFunctionBuilder = new FieldValueFactorFunctionBuilder("seller_remark_score");
            sellerRemarkScoreFunctionBuilder.setWeight(0.1f);
            filterFunctionBuilders[2] = new FunctionScoreQueryBuilder.FilterFunctionBuilder(sellerRemarkScoreFunctionBuilder);

            FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(boolQueryBuilder, filterFunctionBuilders)
                    .boostMode(CombineFunction.SUM)
                    .scoreMode(FunctionScoreQuery.ScoreMode.SUM);

            searchSourceBuilder.query(functionScoreQueryBuilder)
                    .sort("_score", SortOrder.DESC);
        } else {
            FunctionScoreQueryBuilder.FilterFunctionBuilder[] filterFunctionBuilders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[1];
            ScoreFunctionBuilder<FieldValueFactorFunctionBuilder> pricePerManFunctionBuilder = new FieldValueFactorFunctionBuilder("price_per_man");
            pricePerManFunctionBuilder.setWeight(1);
            filterFunctionBuilders[0] = new FunctionScoreQueryBuilder.FilterFunctionBuilder(pricePerManFunctionBuilder);

            FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(boolQueryBuilder, filterFunctionBuilders)
                    .boostMode(CombineFunction.REPLACE)
                    .scoreMode(FunctionScoreQuery.ScoreMode.SUM);
            searchSourceBuilder.query(functionScoreQueryBuilder)
                    .sort("_score", SortOrder.ASC);
        }


        //3.1 编写script_fields返回distance字段
        Map<String, Object> params = new HashMap<>(16);
        params.put("lat", longitude);
        params.put("lon", latitude);
        String lang = "expression";
        String idOrCode = "haversin(lat,lon,doc['location'].lat,doc['location'].lon)";
        Script script = new Script(ScriptType.INLINE, lang, idOrCode, params);

        //4.1 构建聚合
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("group_by_tags").field("tags");


        //想要查询的字段
        String[] includeFields = new String[]{"id"};
        //排除的字段
        String[] excludeFields = new String[]{};

        searchSourceBuilder.scriptField("distance", script)
                .fetchSource(includeFields, excludeFields)
                .aggregation(termsAggregationBuilder);

        searchRequest.source(searchSourceBuilder);
        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            if (RestStatus.OK.equals(searchResponse.status())) {
                List<ShopResponse> shopResponseList = new ArrayList<>();
                SearchHits hits = searchResponse.getHits();
                SearchHit[] searchHits = hits.getHits();
                for (SearchHit hit : searchHits) {
                    //获得ES主键=source里面的id
                    String id = hit.getId();
                    Shop shop = shopService.get(Integer.valueOf(id));
                    ShopResponse shopResponse = MapperFactory.getCopyByRefMapper().mapClass(Shop.class, ShopResponse.class)
                            .registerAndMap(shop, ShopResponse.class);
                    shopResponse.setCategoryModel(shop.getCategoryModel());
                    shopResponse.setSellerModel(shop.getSellerModel());

                    //获得距离
                    Map<String, DocumentField> fields = hit.getFields();
                    DocumentField distanceField = fields.get("distance");
                    BigDecimal disValue = new BigDecimal(distanceField.getValue().toString());
                    shopResponse.setDistance(disValue.multiply(new BigDecimal(1000).setScale(0,BigDecimal.ROUND_CEILING)).intValue());

                    shopResponseList.add(shopResponse);
                }

                List<Map<String, Object>> tagsList = new ArrayList<>();
                Aggregations aggregations = searchResponse.getAggregations();
                Terms byTagsAggregation = aggregations.get("group_by_tags");
                List<? extends Terms.Bucket> buckets = byTagsAggregation.getBuckets();
                for (Terms.Bucket bucket : buckets) {
                    Map<String, Object> tagMap = new HashMap<>(16);
                    long docCount = bucket.getDocCount();
                    String tag = (String) bucket.getKey();
                    tagMap.put("tags", tag);
                    tagMap.put("num", docCount);
                    tagsList.add(tagMap);
                }

                result.put("tags", tagsList);
                result.put("shop", shopResponseList);
            }
        } catch (IOException e) {
            log.error("{}:", e.getMessage());
        }
        return result;
    }

正在回答 回答被采纳积分+3

2回答

龙虾三少 2020-11-23 12:58:14

不需要

0 回复 有任何疑惑可以回复我~
龙虾三少 2020-03-11 22:55:00

没看懂你的问题

0 回复 有任何疑惑可以回复我~
  • 他的意思不想按照你的这种构建jsonObject 直接使用官方文档编写   我目前使用的也是官方文档, 不过老师的这种 我看着更麻烦, 可能是我太菜了  我在研究一下
    回复 有任何疑惑可以回复我~ 2020-11-22 23:23:21
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信