0
点赞
收藏
分享

微信扫一扫

SpringBoot 整合 ES 进行各种高级查询搜索

小黑Neo 2023-05-30 阅读 25

数据准备

因为本文都是数据的搜索,所以我们需要在我们的es服务器里先插入一些数据以供我们后面使用

esUserService

public interface EsUserService extends ElasticsearchRepository<User, Integer> {

}

@RestController
public class EsController {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;
    @Autowired
    private EsUserService esUserService;
    @Autowired
    private RestHighLevelClient client;

    private String[] names = {"诸葛亮", "曹操", "李白", "韩信", "赵云", "小乔", "狄仁杰", "李四", "诸小明", "王五"};
    private String[] infos = {"我来自中国的一个小乡村,地处湖南省", "我来自中国的一个大城市,名叫上海,人们称作魔都"
            , "我来自杭州,这是一个浪漫的城市"};

    /**
     * 准备数据
     *
     * @return
     */
    @GetMapping("prepareDate")
    public Object saveUser() {
        //添加索引mapping索引会自动创建但mapping自只用默认的这会导致分词器不生效 所以这里我们手动导入mapping
        Random random = new Random();
        List<User> users = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            User user = new User();
            user.setId(i);
            user.setName(names[random.nextInt(9)]);
            user.setAge(random.nextInt(40) + i);
            user.setInfo(infos[random.nextInt(2)]);
            users.add(user);
        }
        Iterable<User> users1 = esUserService.saveAll(users);

        return users1;
    }
}

SpringBoot 整合 ES 进行各种高级查询搜索_java

下面开始我们本文的重点

准备map转实体类

由于我们需要频繁的使用map转对象,所以给大家一个比较好用的map转对象方法

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.util.Map;
import java.util.Objects;

/**
 * 利用反射讲数据转化为Object
 *
 * @param <T>
 */
public class BeanHandler<T> {
    private Class<T> clazz;

    public BeanHandler(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 讲sql 查询结果 ResultSet转化为对象
     *
     * @param rs
     * @return
     * @throws Exception
     */
    public T handle(ResultSet rs) throws Exception {
        //结果集默认指向为第一个数据的前一个
        if (rs.next()) {
            //根据传入的字节码创建传入的指定对象
            T obj = clazz.newInstance();
            //获取指定字节码信息
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class);
            //获取所有属性描述器
            PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : pds) {
                //获取结果集中对应字段名的值
                Object o = rs.getObject(pd.getName());
                //执行当前方法并传入参数
                pd.getWriteMethod().invoke(obj, o);
            }
            return obj;
        }
        return null;
    }

    /**
     * 将map 利用反射转化为对象
     *
     * @param map
     * @return
     * @throws Exception
     */
    public T handle(Map<String, Object> map) throws Exception {
        //结果集默认指向为第一个数据的前一个
        //根据传入的字节码创建传入的指定对象
        T obj = clazz.newInstance();
        BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class);
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();

        for (PropertyDescriptor pd : pds) {
            Object o = map.get(pd.getName());
            if (Objects.nonNull(o)) {
                // !!!这里需要对属性类型做强制类型转化,
                o = getPropertyTypeObject(pd, o);
                // 下面的方法相当于属性的 set方法
                pd.getWriteMethod().invoke(obj, o);
            }
        }
        return obj;
    }


    /**
     * 将对应的mapValue 强转为实体类对应的类型
     *
     * @param pd
     * @param o
     * @return
     */
    public Object getPropertyTypeObject(PropertyDescriptor pd, Object o) {
        //当前属性的类型
        String name = pd.getPropertyType().getName();
        name = name.substring(name.lastIndexOf(".") + 1);
        switch (name) {
            case "String":
                o = String.valueOf(o);
                break;
            case "Long":
                o = Long.valueOf(String.valueOf(o));
                break;
            case "Double":
                o = Double.valueOf(String.valueOf(o));
                break;
            case "Integer":
                o = Integer.valueOf(String.valueOf(o));
                break;
            case "BigDecimal":
                o = new BigDecimal(String.valueOf(o));
                break;
        }
        return o;
    }

}

单条件精确查询

@PostMapping("singleConditionPreciseQuery")
public Object singleConditionPreciseQuery(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.matchQuery("name", query));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	List<User> users = new ArrayList<>();
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

范围查询

/**
 * 范围查询
 * 包括from、to
 *
 * @return
 */
@PostMapping("rangeSearch1")
public Object rangeSearch1(@RequestParam(value = "from") int from, @RequestParam(value = "to") int to) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.rangeQuery("age").from(from).to(to));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

/**
 * 范围查询
 * 不包括from、to
 *
 * @return
 */
@PostMapping("rangeSearch2")
public Object rangeSearch2(@RequestParam(value = "from") int from, @RequestParam(value = "to") int to) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.rangeQuery("age").from(from, false).to(to, false));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

/**
 * 范围查询
 * lt:小于,gt:大于
 *
 * @return
 */
@PostMapping("rangeSearch3")
public Object rangeSearch3(@RequestParam(value = "from") int from, @RequestParam(value = "to") int to) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.rangeQuery("age").lt(to).gt(from));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

SpringBoot 整合 ES 进行各种高级查询搜索_java_02

模糊查询,支持通配符

/**
 * 模糊查询,支持通配符
 *
 * @return
 */
@PostMapping("vagueSearch")
public Object vagueSearch(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.wildcardQuery("name", query));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

/**
 * 不使用通配符的模糊查询,左右匹配
 *
 * @return
 */
@PostMapping("vagueSearch1")
public Object vagueSearch1(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.queryStringQuery(query).field("name"));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}
/**
 * 多字段模糊查询
 *
 * @return
 */
@PostMapping("vagueSearch2")
public Object vagueSearch2(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.multiMatchQuery(query, "name", "info"));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

排序

/**
 * 排序
 *
 * @return
 */
@PostMapping("sortSearch")
public Object sortSearch(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.multiMatchQuery(query, "name", "info"))
			.sort("age", SortOrder.ASC);//按照年龄正序

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

精确统计筛选文档数

/**
 * 精确统计筛选文档数,查询性能有所降低
 *
 * @return
 */
@PostMapping("countSearch")
public Object countSearch() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.trackTotalHits(true);
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	return response;
}

设置源字段过滤返回

/**
 * 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
 *  * @return
 */
@PostMapping("filterSearch")
public Object filterSearch() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.fetchSource(new String[]{"name", "age"}, new String[]{"id", "info"});
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

SpringBoot 整合 ES 进行各种高级查询搜索_java_03

通过上图的结果我们也可以看出:

  • 第一个参数结果集包括哪些字段
  • 第二个参数表示结果集不包括哪些字段

SpringBoot 整合 ES 进行各种高级查询搜索_java_04

根据 id 精确匹配

/**
 * 根据Id精准查询
 *
 * @return
 */
@PostMapping("searchByIds")
public Object searchByIds(@RequestBody Map<String, Object> params) throws Exception {
	List<Integer> ids = (List<Integer>) params.get("ids");
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.termsQuery("_id", ids));
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

matchAllQuery 搜索全部

/**
 * matchAllQuery 搜索全部
 *
 * @return
 */
@PostMapping("martchAllQuery")
public Object martchAllQuery() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.matchAllQuery());
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

match 搜索匹配

/**
 * match 搜索匹配
 *
 * @return
 */
@PostMapping("martch")
public Object martch(@RequestBody Map<String, Object> params) throws Exception {
	List<String> querys = (List<String>) params.get("querys");
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.matchQuery("name", querys));
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

bool组合查询

/**
* match 搜索匹配
*
* @return
*/
@PostMapping("martch")
public Object martch(@RequestBody Map<String, Object> params) throws Exception {
List<String> querys = (List<String>) params.get("querys");
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
		.query(QueryBuilders.matchQuery("name", querys));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
searchRequest.types("_doc");    /**
 * bool组合查询
 *
 * @return
 */
@PostMapping("boolSearch")
public Object boolSearch(@RequestBody Map<String, Object> params) throws Exception {
	List<String> queryNames = (List<String>) params.get("names");
	int maxAge = (int) params.get("maxAge");
	int minAge = (int) params.get("minAge");

	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder();
	BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
	boolQueryBuilder.must(QueryBuilders.termsQuery("name", queryNames));
	boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(maxAge).gte(minAge));
	builder.query(boolQueryBuilder);
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 执行请求
List<User> users = new ArrayList<>();
for (SearchHit searchHit : response.getHits().getHits()) {
	Map<String, Object> map = searchHit.getSourceAsMap();
	BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
	User user = beanHandler.handle(map);
	users.add(user);
}
// 解析查询结果
return users;
}

SpringBoot 整合 ES 进行各种高级查询搜索_User_05

nested类型嵌套查询

有时候,我们需要查询一个对象内部类的值,发现通过平时的查询查询不到数据,这时DSL(Domain Specific language,即特定领域专用语言)出场了!

elasticsearch中的内部对象无法按预期工作,这里的问题是elasticsearch(lucene)使用的库没有内部对象的概念,因此内部对象被扁平化为一个简单的字段名称和值列表。

/**
 * nested类型嵌套查询
 *
 * @return
 */
@PostMapping("nestedSearch")
public Object nestedSearch() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder();
	//条件查询
	BoolQueryBuilder mainBool=new BoolQueryBuilder();
	mainBool.must(QueryBuilders.matchQuery("name", "赵六"));
	//nested类型嵌套查询
	BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
	boolQueryBuilder.must(QueryBuilders.matchQuery("user.name", "A"));
	boolQueryBuilder.must(QueryBuilders.matchQuery("user.info", "浦东"));
	NestedQueryBuilder nested = QueryBuilders.nestedQuery("user",boolQueryBuilder, ScoreMode.None);
	mainBool.must(nested);
	builder.query(mainBool);
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

多条件查询 + 排序 + 分页

/**
 * 多条件查询 + 排序 + 分页
 *
 * @return
 */
@PostMapping("multiConditionSearch")
public Object multiConditionSearch() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder();
	//条件搜索
	BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
	boolQueryBuilder.must(QueryBuilders.matchQuery
	("name", "张").operator(Operator.AND);//需要 满足所有字段);
	boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));
	builder.query(boolQueryBuilder);
	//结果集合分页
	builder.from(0).size(2);

	//排序
	builder.sort("age",SortOrder.ASC);
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

聚合查询

/**
 * 求和
 *
 * @return
 */
@PostMapping("sumSearch")
public Object sumSearch() throws Exception {
	Map<String, Object> result = new HashMap<>();
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.termsQuery("_id", new int[]{1, 2, 3}));
	//条件搜索
	//结果集合分页
	builder.from(0).size(2);
	builder.query(QueryBuilders.matchAllQuery());
	//聚合查询
	AggregationBuilder aggregation = AggregationBuilders.sum("sum_age").field("age");
	builder.aggregation(aggregation);

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	return response;
}

SpringBoot 整合 ES 进行各种高级查询搜索_User_06

SpringBoot 整合 ES 进行各种高级查询搜索_User_07

值得我们注意的是在进行聚合操作的fild上,如果我们该字段设置成key或者text,则会出现以下错误

SpringBoot 整合 ES 进行各种高级查询搜索_User_08

原因是:

文本字段未针对需要每个文档字段数据(如聚合和排序)的操作进行优化,因此默认情况下禁用这些操作。

我们需要改用关键字字段。或者,在设置了text或者key的字段上设置fielddata=true,以便通过取消反转索引来加载字段数据。请注意,这可能会占用大量内存

参考文章并稍作修改,https://blog.csdn.net/zhiyikeji/article/details/128939901

举报

相关推荐

0 条评论