目录
4、java中匹配ES中多个字段查询(为什么加上.keyword反而无结果了呢?)
6、检索字段排序-NativeSearchQueryBuilder
1、检索ES数据库
/**
* @Description: 通过企业类型查询企业名称
* @MethodName: queryOrgNameByEnterprisesType
* @Param enterprisesType: 企业类型(例如:研究所/学校)
* @Return java.util.List<java.lang.String> 返回企业名称的集合
* @Author Zhangtd
* @Date 2020/2/28
*/
public List<String> queryOrgNameByEnterprisesType(String enterprisesType){
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//因为使用termQuery(),数据库中字段enterprisesType要加".keyword"
boolQueryBuilder.must(QueryBuilders.termQuery("enterprisesType.keyword",enterprisesType));
Iterable<SimpleOrg> search = orgRepository.search(boolQueryBuilder);
List<String> orgNameList = Lists.newArrayList();
for (SimpleOrg simpleOrg : search) {
orgNameList.add(simpleOrg.getName());
}
return orgNameList;
}
2、检索下级数据
for (String param : aggregationParam) {
TermsAggregationBuilder size = AggregationBuilders.terms(param).field(param).size(300);
//查询下级数据size.build(AggregationBuilders.terms())
nativeSearchQueryBuilder.addAggregation(size);
}
AggregatedPage<FileManagement> search =
(AggregatedPage<FileManagement>) fileRepository.search(nativeSearchQueryBuilder.build());
Map<String, Aggregation> asMap = search.getAggregations().getAsMap();
for (int i = 0; i < aggregationParam.length; i++) {
Terms terms = (Terms) asMap.get(aggregationParam[i]);
List<String> arrayList = new ArrayList<>();
for (Terms.Bucket bucket : terms.getBuckets()) {
String s1 = bucket.getKey().toString();
arrayList.add(s1);
long docCount = bucket.getDocCount();
}
//startYear只要最小年份,endYear只要最大的年份
if ("startYear".equals(aliasAggregationParam[i])) {
Collections.sort(arrayList);
hashMap.put(aliasAggregationParam[i], arrayList.get(0));
}
if ("endYear".equals(aliasAggregationParam[i+1])) {
Collections.sort(arrayList);
hashMap.put(aliasAggregationParam[i+1], arrayList.get(arrayList.size() - 1));
} else {
hashMap.put(aliasAggregationParam[i], arrayList);
}
}
3-1、检索多个字段,匹配同一个值
3-2、.must()
如果使用.must(),那么检索条件中必须满足检索要求,但是检索时候会对“keyword”内容进行拆分(例如“张三”会拆成“张”、“三”两个词检索,满足一个就会返回)
bqbStraAgree.must(QueryBuilders.multiMatchQuery(keyWord,"province","city"));
3-3、.should()
如果使用.should(),那么检索结果中不满足该条件也会返回,只是满足该条件的会排在前面
bqbStraAgree.should(QueryBuilders.multiMatchQuery(keyWord,"province","city"));
3-3-1、.should()--一个key多个value
//构造类型查询条件
BoolQueryBuilder typeQueryBuilder = new BoolQueryBuilder();
//must连接其他条件,相当于and;should相当于or
boolQueryBuilder.must(typeQueryBuilder.should(QueryBuilders.termQuery("type", 0))
.should(QueryBuilders.termQuery("type", 1)));
参考:https://blog.csdn.net/hu_zhiting/article/details/110956879
4、java中匹配ES中多个字段查询(为什么加上.keyword反而无结果了呢?)
public List<String> queryOrgNameByEnterprisesType(String enterprisesType) {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("enterprisesType.keyword", enterprisesType));
//查询有结果
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("name", "农业"));
//查询无结果
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("name.keyword", "农业"));
//boolQueryBuilder.must(QueryBuilders.matchPhrasePrefixQuery("name.keyword",orgName));
Iterable<SimpleOrg> search = orgRepository.search(boolQueryBuilder);
List<String> orgNameList = Lists.newArrayList();
//去重
for (SimpleOrg simpleOrg : search) {
if (!orgNameList.contains(simpleOrg.getName())) {
orgNameList.add(simpleOrg.getName());
}
}
return orgNameList;
}
5-1、检索ES数据库--未超过1W条
BoolQueryBuilder bqbUnincorpUnit = boolQuery();
bqbUnincorpUnit.must(QueryBuilders.rangeQuery("establishmentYear").to(year,true))
.must(QueryBuilders.termQuery("enterprisesType.keyword", "非法人"))
.must(QueryBuilders.matchPhraseQuery("province", keyWord));
//如果返回结果超过1W条,这里会报异常
Iterable<SimpleOrg> searchUnincorpUnit = orgRepository.search(bqbUnincorpUnit);
reportVo.setUnincorporatedUnitCount(CommonUtils.iterableCount(searchUnincorpUnit));
5-2、检索ES数据库--超过1W条,可以通过分页查询实现
BoolQueryBuilder bqbPatent = boolQuery();
bqbPatent.must(QueryBuilders.rangeQuery("year").to(year,true))
.must(QueryBuilders.matchPhraseQuery("province", keyWord));
Pageable pageable = PageRequest.of(0, 10);
SearchQuery queryPatent = new NativeSearchQueryBuilder()
.withQuery(bqbPatent).withPageable(pageable).build();
Page<Patent> patentPage = patentRepository.search(queryPatent);
System.out.println("个数:"+patentPage.getTotalElements());
6、检索字段排序-NativeSearchQueryBuilder
public Result getScienceDeputyList(HttpServletRequest request) {
Result result = new Result();
result.setCode("200");
int offset = Integer.valueOf(request.getParameter("offset")) - 1;
int limit = Integer.valueOf(request.getParameter("limit"));
String province = request.getParameter("dispatch.fromOrg.Province");
String year = request.getParameter("dispatch.fromYear");
String orgName = request.getParameter("dispatch.fromOrg.orgName");
//排序
Pageable pageable = PageRequest.of(offset, limit, Sort.Direction.DESC, "dispatch.fromYear.keyword");
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
if (StringUtils.isNotEmpty(province)) {
boolQueryBuilder.must(QueryBuilders.termQuery("dispatch.fromOrg.Province.keyword", province));
}
if (StringUtils.isNotEmpty(year)) {
boolQueryBuilder.must(QueryBuilders.termQuery("dispatch.fromYear.keyword", year));
}
if (StringUtils.isNotEmpty(orgName)) {
boolQueryBuilder.must(QueryBuilders.termQuery("dispatch.fromOrg.orgName.keyword", orgName));
}
nativeSearchQueryBuilder.withQuery(boolQueryBuilder).withPageable(pageable);
Page<ScienceDeputy> page = scienceDeputyRepository.search(nativeSearchQueryBuilder.build());
Map<String, Object> contentMap = new HashMap<>();
contentMap.put("content", page.getContent());
result.setData(contentMap);
result.setPageSize(page.getSize());
result.setPageNumber(page.getNumber());
result.setCount(page.getTotalElements());
return result;
}
#或者构建sortBuilder
FieldSortBuilder sortBuilder = SortBuilders.fieldSort("signDate").order(SortOrder.ASC);
nativeSearchQueryBuilder.withQuery(bqbAgreement).withSort(sortBuilder);
7、聚合检索ES-某个字段下所有的值(去重)
方法一:聚合
public Result newsType() {
Map<String, Object> resultMap = new HashMap<>();
List<String> typeList = new ArrayList<>();
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("secondFileType").field("secondFileType.keyword");
nativeSearchQueryBuilder.addAggregation(aggregationBuilder);
AggregatedPage<News> aggregatedPage = (AggregatedPage<News>) newsRepository.search(nativeSearchQueryBuilder.build());
Terms terms = (Terms) aggregatedPage.getAggregations().getAsMap().get("secondFileType");
for (Terms.Bucket bucket : terms.getBuckets()) {
typeList.add(bucket.getKey().toString());
}
resultMap.put("content",typeList);
return success(resultMap);
}
方法二:Collapse
返回的是去重后整行数据,不是只某个字段
#对“adminPartOf”这个字段中的内容去重(类型)
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withCollapseField("adminPartOf.keyword");
Page<SimpleOrg> search1 = orgRepository.search(nativeSearchQueryBuilder.build());
#依赖
<!--<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>-->
8、自定义检索
public void test1(){
String field = "instName";
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//检索条件(departureDate字段的值不为空字符串)
boolQueryBuilder.mustNot(QueryBuilders.termQuery("departureDate.keyword", ""));
//查询结果条件(查询100条数据,按照departureDate字段升序排序返回)
PageRequest of = PageRequest.of(0, 100, Sort.Direction.ASC, "departureDate.keyword");
NativeSearchQuery build = nativeSearchQueryBuilder
.withQuery(boolQueryBuilder)
//聚合结果条件(返回13条)
.addAggregation(AggregationBuilders.terms(field).field(field+".keyword").size(13))
.withPageable(of)
.build();
AggregatedPage<VisitOut> aggregatedPage = elasticsearchTemplate.queryForPage(build, VisitOut.class);
//获取正常查询数据
List<VisitOut> content1 = aggregatedPage.getContent();
System.out.println(JSON.toJSONString(content1, true));
//获取聚合数据
Aggregations aggregations = aggregatedPage.getAggregations();
Map<String, Aggregation> asMap = aggregations.getAsMap();
List<Map<String, Object>> list = new ArrayList<>();
for (Terms.Bucket bucket : ((Terms) asMap.get(field)).getBuckets()) {
Map<String, Object> map = new HashMap<>();
map.put(bucket.getKeyAsString(), bucket.getDocCount());
list.add(map);
}
System.out.println(JSON.toJSONString(list, true));
}
9、Cardinality去重
NativeSearchQueryBuilder pifiNSQB = new NativeSearchQueryBuilder();
BoolQueryBuilder pifiBQB = QueryBuilders.boolQuery();
//检索条件
pifiBQB.must(QueryBuilders.termQuery("perYear.keyword", year))
.must(QueryBuilders.termQuery("perType.keyword", "访问学者"));
NativeSearchQuery pifiBuild = pifiNSQB
.withQuery(pifiBQB)
//聚合字段
.addAggregation(
//统计人名去重后的数量
AggregationBuilders.cardinality("count").field("name.keyword"))
.build();
//---------------------------------(AggregatedPage<T>)
AggregatedPage<InternationalPerson> search = (AggregatedPage<InternationalPerson>) internPersonRepository.search(pifiBuild);
Cardinality cardinality = search.getAggregations().get("count");
long value = cardinality.getValue();
10、filter与query比较
filter:不排序、没有相关度评分,速度较快;
query:根据相关度评分排序,速度较慢;
11、分词器
1、ik中文分词器以及在线停用词
elasticsearch ik中文分词器的使用详解 - Reynold.C - 博客园