【elasticsearch】ES的JAVA工具类完整版(已完成,已测试)

springboot 的 elasticsearch 版本:

7.15.2

前情提要:

1.首先要理解 elasticsearch 对于【数据类型】很严格,如果字段类型不规范,在 检索/排序/聚合 时候类型不正确就会出现报错或者查不到数据的问题。所以在一般String类型插入结构如下:

这样的结构,不仅可以支持分词查询,也可以进行精准匹配、对该字段排序、对该字段进行聚合。一箭双雕,通常String都建议用这样的结构。

2.如果是数值类型(Integer、Long、Double)更适合进行排序、聚合、精准匹配。如果确定某类的某个属性是【数值】,最好不要使用String接收(并非完全不可使用),用数值类型接收更合理。如下:
在这里插入图片描述

3.如果某个类的属性是Object类型,在进行检索、聚合等操作时,es的type类型不必做其它操作,如下:
在这里插入图片描述
像 tradeType、map 这两个属性属于Object类型,在es中不必特殊指定类型,如下:
在这里插入图片描述

4.es中的【nested】类型,特定用在某属性是数组类型,而且该属性在es结构中必须要加上【nested】类型,否在在检索、聚合时候就会出现报错或查不到数据问题,以下:
在这里插入图片描述

es中结构如下:
在这里插入图片描述

subjectList 便是数组类型,并且泛型是包装类型,在es中都需要指定该字段是【nested】。

5.非常注意:如果某属性的泛型是基本类型(比如:List< String >、List< Integer > )那es的类型可不是【nested】,而是keyword或Integer 这种。如下:
在这里插入图片描述
es中的结构:
在这里插入图片描述
当然会有朋友问,es中貌似也支持array类型,但是我用的版本在使用 array 创建索引时会报错:No handler for type [array]。所以我这边会用keyword类型。
具体支持类型,可参考:Elasticsearch数据类型及其属性

准备索引:

通过es控制台或者postman都可以进行索引操作,类型mysql可视化工具对mysql数据库表结构操作类型,只不过,es对于创建后的索引的字段类型不可改变,如果一定要变更字段类型,就需要删除索引重新创建,这就是为什么对于要插入的数据类型严格控制的原因

1.创建索引:createIndex():
当你制作好一个java类,并且把属性的类型都规范好,这时候可直接通过该方法创建索引,如果该类中有数组类型的属性:
1.如果数组泛型是基本类型 则 传入 arrayField 参数,在es中type=keyword。
2.如果数组泛型是包装类型 则需要指定 nestedField 参数的属性名,否则在插入数据后会发现,该数组类型的es中的type不是 nested类型。

2.删除索引:deleteIndex(String indexName):
不解释了,没啥好说的。

3.是否存在指定索引:existIndex(String indexName):
不解释了,没啥好说的。

完整示例:

工具类用的json格式化工具:
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

java实体类:
@Data
public class UserIndexReqDTO implements Serializable {
   
    private static final long serialVersionUID = 1L;
    /**
     * [描述] 用户id
     */
    private Long id;
    private String userName;
    private Integer sex;
    private Integer age;

    /** 用户多个手机号码 */
    private List<String> phoneList;


    /** 用户科目列表信息 */
    private List<SubjectDTO> subjectList;


}
@Data
 class SubjectDTO {
   
    /** 科目id */
    private Integer id;
    /** 科目名称 */
    private String subjectName;
    /** 科目分值 */
    private Integer subjectScore;
}

1.创建索引示例:
    @Resource
    private EsClientUtil2 esClientUtil2;
    private String indexName = "user_index";

    @Override
    public BaseResponse<Object> addMore( @RequestBody List<UserIndexReqDTO> list){
   
		// 如果指定索引不存在,则按要求创建
        if(!esClientUtil2.existIndex(indexName)){
   
            esClientUtil2.createIndex(indexName,Arrays.asList("phoneList"),Arrays.asList("subjectList"));
        }
        Assert.notEmpty(list,"list is empty");
        List<JSONObject> collect = list.stream()
                .map(item -> JSONObject.parseObject(JSONObject.toJSONString(item), JSONObject.class))
                .collect(Collectors.toList());
        boolean addDoc = esClientUtil2.multiAddDoc(indexName, collect);
        return BaseResponse.ofSuccess(addDoc);
    }
2.准备测试数据:
[
    {
   
        "id": 48,
        "userName": "小明",
        "sex": 1,
        "age": 17,
        "phoneList": [
            "15800000001",
            "15800000002"
        ],
        "subjectList": [
            {
   
                "id": 62,
                "subjectName": "语文",
                "subjectScore": 68
            }
        ]
    },
    {
   
        "id": 49,
        "userName": "史泰龙小红",
        "sex": 0,
        "age": 10,
        "phoneList": [
            "18732000000",
            "18732000001"
        ],
        "subjectList": [
            {
   
                "id": 62,
                "subjectName": "语文",
                "subjectScore": 68
            },
            {
   
                "id": 63,
                "subjectName": "数学",
                "subjectScore": 30
            }
        ]
    },
    {
   
        "id": 50,
        "userName": "小黑",
        "sex": 1,
        "age": 14,
        "phoneList": [
            "13200000000",
            "13200000001"
        ],
        "subjectList": [
            {
   
                "id": 62,
                "subjectName": "语文",
                "subjectScore": 68
            },
            {
   
                "id": 64,
                "subjectName": "英语",
                "subjectScore": 80
            }
        ]
    }
]
3.根据条件查询:
    public BaseResponse<Object> search() {
   
        int pageNum = 1;
        int pageSize = 100;
        Map<String,List<String>> likeMap = new HashMap<>(3);
        Map<String,Object> signMap = new HashMap<>(3);
        Map<String,List<String>> multipleMap = new HashMap<>(3);
        Map<String,List<Long>> rangeMap = new HashMap<>(3);
        List<String> idList = new ArrayList<>();

        // 根据值模糊查询 匹配多字段
        //likeMap.put("小明",Arrays.asList("name","nickName"));
        // 根据值精准匹配 匹配单字段
        //signMap.put("sex","1");
        //signMap.put("phoneList",Arrays.asList("15800000001","18732000001"));
        // 根据值精准匹配 匹配多字段
        //multipleMap.put("小红",Arrays.asList("name","nickName"));
        // 区间匹配  18<= age <= 40
        //rangeMap.put("age",Arrays.asList(18L,40L));
        // 根据esId进行检索
        //idList = Arrays.asList("1","2","3");

        //嵌套查询
        Map<String,String> key = new HashMap<>(1);
        Map<String,List<String>> value = new HashMap<>(1);
        //key.put("subjectList", "subjectList.id");
        //value.put("subjectList.id",Arrays.asList("63"));
        List<NestedQueryBuilder> nestedListQuery = esClientUtil2.getNestedListQuery(key, value);

        BoolQueryBuilder builder = esClientUtil2.getQueryBuilderAnd(likeMap, signMap, multipleMap, rangeMap, nestedListQuery, idList);
        PageResult<String> search = esClientUtil2.search(EsConstant.ESALES_USER_COLLECT_INDEX,
                builder, null,
                null, null, null, pageNum, pageSize);
        List<UserIndexReqDTO> result = new ArrayList<>();
        for (String s : search.getList()) {
   
            result.add(JSONObject.parseObject(s, UserIndexReqDTO.class));
        }
        return BaseResponse.ofSuccess(result);
    }
4.根据条件聚合:
    public BaseResponse<Object> group() {
   
        Map<String,List<String>> likeMap = new HashMap<>(3);
        Map<String,Object> signMap = new HashMap<>(3);
        Map<String,List<String>> multipleMap = new HashMap<>(3);
        Map<String,List<Long>> rangeMap = new HashMap<>(3);
        List<String> idList = new ArrayList<>();

        // 根据值模糊查询 匹配多字段
        //likeMap.put("小明",Arrays.asList("name","nickName"));
        // 根据值精准匹配 匹配单字段
        //signMap.put("sex","1");
        //signMap.put("phoneList",Arrays.asList("15800000001","18732000001"));
        // 根据值精准匹配 匹配多字段
        //multipleMap.put("小红",Arrays.asList("name","nickName"));
        // 区间匹配  18<= age <= 40
        //rangeMap.put("age",Arrays.asList(18L,40L));
        // 根据esId进行检索
        //idList = Arrays.asList("1","2","3");

        //嵌套查询
        Map<String,String> key = new HashMap<>(1);
        Map<String,List<String>> value = new HashMap<>(1);
        //key.put("subjectList", "subjectList.id");
        //value.put("subjectList.id",Arrays.asList("63"));
        List<NestedQueryBuilder> nestedListQuery = esClientUtil2.getNestedListQuery(key, value);
        BoolQueryBuilder builder = esClientUtil2.getQueryBuilderAnd(likeMap, signMap, multipleMap, rangeMap, nestedListQuery, idList);

        // 根据字段进行聚合
        List<Map<String, Object>> sex = esClientUtil2.group(EsConstant.ESALES_USER_COLLECT_INDEX,
                "sex",null, builder,
                null, null, null);
        for (Map<String, Object> map : sex) {
   
            System.out.println(map);
        }
        
        // 根据 嵌套 字段进行聚合
        List<Map<String, Object>> subjectIdList = esClientUtil2.group(EsConstant.ESALES_USER_COLLECT_INDEX,
                null,Arrays.asList("subjectList","subjectList.id"), builder,
                null, null, null);
        for (Map<String, Object> map : subjectIdList) {
   
            System.out.println(map);
        }
        return BaseResponse.ofSuccess(sex);
    }
4-1.after翻页:
    public BaseResponse<Object> search() {
   
        Map<String,List<String>> likeMap = new HashMap<>(3);
        Map<String,Object> signMap = new HashMap<>(3);
        Map<String,List<String>> multipleMap = new HashMap<>(3);
        Map<String,List<Long>> rangeMap = new HashMap<>(3);
        List<String> idList = new ArrayList<>();

        // 根据值模糊查询 匹配多字段
        //likeMap.put("小明",Arrays.asList("name","nickName"));
        // 根据值精准匹配 匹配单字段
        //signMap.put("sex","1");
        //signMap.put("phoneLis
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值