es新建索引,搜索

PUT /order_auto/
{
"settings":{
"index":{
"number_of_shards" : "3",
"number_of_replicas" : "0"
}
}
}
 
PUT /order_auto/_doc/_mappings?include_type_name=true
{
"properties": {
"id": {
"type": "keyword"
},
"orderNo": {
"type": "keyword"
},
"status": {
"type": "text"
},
"pushed": {
"type": "keyword"
},
"requestDecisionNo": {
"type": "keyword"
},
"initParam": {
"type": "keyword"
},
"customerId": {
"type": "keyword"
},
"name": {
"type": "keyword"
},
"channelId": {
"type": "keyword"
},
"channelName": {
"type": "keyword"
},
"idCard": {
"type": "keyword"
},
"phone": {
"type": "text"
},
"operateType": {
"type": "keyword"
},
"requestDecisionParam": {
"type": "keyword"
},
"requestManualParam": {
"type": "keyword"
},
"manualResult": {
"type": "keyword"
},
"decisionResult": {
"type": "keyword"
},
"sceneNo": {
"type": "keyword"
},
"storeFlag": {
"type": "keyword"
},
"artificialFlag": {
"type": "keyword"
},
"manualPushed": {
"type": "keyword"
},
"branchInfo": {
"type": "keyword"
},
"createTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"updateTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}

上面,新建es索引。

es搜索

package com.mark.order.web.base.configures.es;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mark.order.domain.consts.Const;
import com.mark.order.domain.dto.OrderEs;
import com.mark.order.domain.enums.order.OrderStateEnum;
import com.mark.order.domain.enums.order.OrderStateVOEnum;
import com.mark.order.domain.vo.orderquery.OrderQueryReqParam;
import com.mark.order.domain.vo.orderquery.OrderQueryRespVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * @author : mark
 * @desc : es工具类
 * @since : 2021/8/27 15:33
 */
@Slf4j
@Component
public class ElasticSearchOperation {

    @Resource
    EsConfig esConfig;

    private final RestHighLevelClient restHighLevelClient;

    public ElasticSearchOperation(RestHighLevelClient restHighLevelClient) {
        this.restHighLevelClient = restHighLevelClient;
    }

    /**
     * 新增数据到es
     *
     * @param indexName 索引名称
     * @param data      对象
     * @param indexId   索引id
     */
    public boolean add(String indexName, Object data, String indexId) {
        if (indexName == null || data == null || indexId == null) {
            return false;
        }
        IndexRequest request = new IndexRequest(indexName);
        request.id(indexId);
        request.source(JSONObject.toJSONString(data), XContentType.JSON);
        try {
            IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
            if (indexResponse == null) {
                return false;
            }
            log.info("写入es成功,风控订单号:{}", indexId);
            return (indexResponse.getResult() == DocWriteResponse.Result.CREATED
                    || indexResponse.getResult() == DocWriteResponse.Result.UPDATED);
        } catch (Throwable e) {
            log.error(
                    "ElasticSearchGateway#add's params  indexName={} and data={} and indexId = {} and Exception Occurred:",
                    indexName, JSONObject.toJSONString(data), indexId, e);
        }
        return false;
    }


    /**
     * 更新数据
     */
    public Boolean update(OrderEs orderEs) {
        log.info("更新订单到es请求参数:{}", JSON.toJSONString(orderEs));
        UpdateRequest updateRequest = new UpdateRequest(esConfig.getIndexName(), String.valueOf(orderEs.getId()));
        updateRequest.retryOnConflict(3);
        updateRequest.doc(JSON.toJSONString(orderEs), XContentType.JSON);
        // 操作ES
        UpdateResponse updateResponse = null;
        try {
            log.info("es更新数据,rq:{}", JSON.toJSONString(updateRequest));
            updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("es订单更新失败", e);
        }
        return updateResponse != null && updateResponse.status().getStatus() == 200;
    }


    /**
     * 查询es
     */
    public Map<String, Object> search(OrderQueryReqParam entity) throws IOException {
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        String status = entity.getStatus();
        if (StrUtil.isNotEmpty(status)) {
            //待决策和初始化
            if (String.valueOf(OrderStateVOEnum.待审核.getCode()).equals(status)) {
                TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("status",
                        OrderStateEnum.待决策.getCode(), String.valueOf(OrderStateEnum.初始化.getCode()));
                boolBuilder.must(termsQuery);
            }
            //待人工审核,人工审核中
            if (String.valueOf(OrderStateVOEnum.电核中.getCode()).equals(status)) {
                TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("status",
                        OrderStateEnum.待人工审核.getCode(), String.valueOf(OrderStateEnum.人工审核中.getCode()));
                boolBuilder.must(termsQuery);
            }
            //机核挂起
            MatchQueryBuilder matchQueryBuilder = null;
            if (String.valueOf(OrderStateVOEnum.机核挂起.getCode()).equals(status)) {
                matchQueryBuilder = QueryBuilders.matchQuery("status",
                        OrderStateEnum.挂起.getCode());
                boolBuilder.must(matchQueryBuilder);
            }
            //外部取消
            if (String.valueOf(OrderStateVOEnum.外部取消.getCode()).equals(status)) {
                matchQueryBuilder = QueryBuilders.matchQuery("status",
                        OrderStateEnum.已取消.getCode());
            }
            if (String.valueOf(OrderStateVOEnum.审核通过.getCode()).equals(status)) {
                matchQueryBuilder = QueryBuilders.matchQuery("status", status);
            }
            if (String.valueOf(OrderStateVOEnum.审核拒绝.getCode()).equals(status)) {
                matchQueryBuilder = QueryBuilders.matchQuery("status", status);
            }
            boolBuilder.must(matchQueryBuilder);
        }
        if (Const.STORE_ORDER.equals(entity.getStoreFlag())) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("storeFlag", entity.getStoreFlag());
            boolBuilder.must(matchQueryBuilder);
        }
        if (StrUtil.isNotEmpty(entity.getOrderNo())) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("orderNo", entity.getOrderNo());
            boolBuilder.must(matchQueryBuilder);
        }
        if (StrUtil.isNotEmpty(entity.getCustomerId())) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("customerId", entity.getCustomerId());
            boolBuilder.must(matchQueryBuilder);
        }
        if (StrUtil.isNotEmpty(entity.getChannelId())) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("channelId", entity.getChannelId());
            boolBuilder.must(matchQueryBuilder);
        }
        if (StrUtil.isNotEmpty(entity.getFkOrderNo())) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("id", entity.getFkOrderNo());
            boolBuilder.must(matchQueryBuilder);
        }
        if (StrUtil.isNotEmpty(entity.getBranchInfo())) {
            WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("branchInfo", "*" + entity.getBranchInfo() + "*");
            boolBuilder.must(wildcardQueryBuilder);
        }
        if (StrUtil.isNotEmpty(entity.getDecisionResult())) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("decisionResult", entity.getDecisionResult());
            boolBuilder.must(matchQueryBuilder);
        }
        if (StrUtil.isNotEmpty(entity.getArtificialFlag())) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("artificialFlag", entity.getArtificialFlag());
            boolBuilder.must(matchQueryBuilder);
        }
        if (StrUtil.isNotEmpty(entity.getSceneCode())) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("sceneCode", entity.getSceneCode());
            boolBuilder.must(matchQueryBuilder);
        }
        if (StrUtil.isNotEmpty(entity.getStartTime()) && StrUtil.isNotEmpty(entity.getEndTime())) {
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("createTime");
            rangeQueryBuilder.gte(entity.getStartTime());
            rangeQueryBuilder.lte(entity.getEndTime());
            boolBuilder.must(rangeQueryBuilder);
        }

        sourceBuilder.query(boolBuilder);
        sourceBuilder.from((entity.getPageNum() - 1) * entity.getPageSize());
        sourceBuilder.size(entity.getPageSize());
        sourceBuilder.timeout(new TimeValue(20, TimeUnit.SECONDS));
        String[] fields = {"id", "orderNo", "status", "requestDecisionNo", "customerId", "name", "channelId", "channelName",
                "idCard", "phone", "operateType", "requestDecisionTime", "decisionResult", "sceneNo", "sceneName",
                "createTime", "updateTime", "artificialFlag", "manualPushed", "storeFlag", "branchInfo"};
        sourceBuilder.fetchSource(fields, new String[]{});
        SearchRequest searchRequest = new SearchRequest(esConfig.getIndexName());
        //按照更新时间排序
        FieldSortBuilder fsb = SortBuilders.fieldSort("createTime");
        fsb.order(SortOrder.DESC);
        sourceBuilder.sort(fsb);
        sourceBuilder.query(boolBuilder);
        sourceBuilder.trackTotalHits(true);
        searchRequest.source(sourceBuilder);
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        List<Map<String, Object>> result = setSearchResponse(response);
        log.info("查询响应:{}", result);
        List<OrderQueryRespVO> list = new ArrayList<>();
        for (Map<String, Object> stringObjectMap : result) {
            OrderQueryRespVO vo = MapToBean(stringObjectMap, OrderQueryRespVO.class);
            //做状态映射
            vo.setStatusValue(cast(vo.getStatus()));
            list.add(vo);
        }
        Map<String, Object> map = new HashMap<>(4);
        map.put("list", list);
        map.put("total", response.getHits().getTotalHits().value);
        return map;
    }

    /**
     * 查询结果转map
     */
    private List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse) {
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            list.add(sourceAsMap);
        }
        return list;
    }


    /**
     * map转对象
     */
    public static <T> T MapToBean(Map<String, ?> map, Class<T> clazz) {
        try {
            T bean = clazz.newInstance();
            BeanUtils.populate(bean, map);
            return bean;
        } catch (Exception e) {
            log.error("map转对象异常");
        }
        return null;
    }


    /**
     * @param status 任务驱动使用的状态
     * @return 展示给页面的状态
     */
    public String cast(Integer status) {
        //待审核
        if (OrderStateEnum.初始化.getCode().equals(status) ||
                OrderStateEnum.待决策.getCode().equals(status)) {
            return OrderStateVOEnum.待审核.getValue();
        }
        //机核中
        if (OrderStateEnum.决策中.getCode().equals(status)) {
            return OrderStateVOEnum.机核中.getValue();
        }
        //电核中
        if (OrderStateEnum.待人工审核.getCode().equals(status) ||
                OrderStateEnum.人工审核中.getCode().equals(status)) {
            return OrderStateVOEnum.电核中.getValue();
        }
        //审核通过
        if (OrderStateEnum.审核通过.getCode().equals(status)) {
            return OrderStateVOEnum.审核通过.getValue();
        }
        //审核拒绝
        if (OrderStateEnum.审核拒绝.getCode().equals(status)) {
            return OrderStateVOEnum.审核拒绝.getValue();
        }
        //外部取消
        if (OrderStateEnum.已取消.getCode().equals(status)) {
            return OrderStateVOEnum.外部取消.getValue();
        }
        return OrderStateVOEnum.机核挂起.getValue();
    }


}

组合查询

现实的查询需求从来都没有那么简单;它们需要在多个字段上查询多种多样的文本,并且根据一系列的标准来过滤。为了构建类似的高级查询,你需要一种能够将多查询组合成单一查询的查询方法。

你可以用 bool 查询来实现你的需求。这种查询将多查询组合在一起,成为用户自己想要的布尔查询(Bool)。

它接收以下参数:

1.must
文档 必须 匹配这些条件才能被包含进来。

相当于sql中的 and

2.must_not
文档 必须不 匹配这些条件才能被包含进来。

相当于sql中的 not

3.should
如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。

相当于sql中的or

4.filter
必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。

每一个子查询都独自地计算文档的相关性得分。一旦他们的得分被计算出来, bool 查询就将这些得分进行合并并且返回一个代表整个布尔操作的得分score。\

示例:下面的查询用于查找 title 字段匹配 how to make millions 并且不被标识为 spam 的文档。那些被标识为 starred 或在2014之后的文档,将比另外那些文档拥有更高的排名。如果 两者 都满足,那么它排名将更高:
 

{
    "bool": {
        "must":     { "match": { "title": "how to make millions" }},
        "must_not": { "match": { "tag":   "spam" }},
        "should": [
            { "match": { "tag": "starred" }},
            { "range": { "date": { "gte": "2014-01-01" }}}
        ]
    }
}

java

   BoolQueryBuilder defaultQueryBuilder = QueryBuilders.boolQuery();
        defaultQueryBuilder.must(QueryBuilders.matchQuery("title", "how to make millions"))
                .mustNot(QueryBuilders.matchQuery("tag", "span"))
                .should(QueryBuilders.matchQuery("tag", "starred"))
                .should(QueryBuilders.rangeQuery("date").gte("2014-01-01"));

filter用法

{
    "bool": {
        "must":     { "match": { "title": "how to make millions" }},
        "must_not": { "match": { "tag":   "spam" }},
        "should": [
            { "match": { "tag": "starred" }}
        ],
        "filter": {
          "range": { "date": { "gte": "2014-01-01" }} 
        }
    }
}

filter中的条件不参与评分score排序

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值