Java+springboot+elasticsearch7.6.2实现分组查询(平级+层级)并实现script多字段拼接查询
简介:关于elasticsearch的“层级”聚合,百度一下有一大堆文章。这里不再啰嗦了,由于百度了三个小时,也没找到我想要的"平级"查询的方法,最后还是自己研究源码整除来的,其实就是那么那么简单,只是没有例子,就不好整。上干货。
注:对es里的专业用语不熟,所以这里用的"平级","层级"两个测只是形象词语,不是es专业叫法。。。知道叫法的请留言告知。
目录
Java+springboot+elasticsearch7.6.2实现分组查询(平级+层级)并实现script多字段拼接查询
第一步、 实现平级搜索。
先看一下,测试数据的数据结构:
kibana:
GET ermsftrv1/_search
{
"query": {
"match_all": {}
}
}
结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 6,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6502586031240448",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新建文本文档",
"archNo" : "0022-SB0000.TODO-TODO-001",
"archTypeCode" : "SB0000",
"archTypeId" : "6485930821313792",
"archTypeName" : "设备仪器",
"archivedDate" : 1587545484000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6502586302145792,
"id" : "6502586031240448",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "hanfeixian",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650556800000,
"secretId" : "2",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000722",
"writingDate" : 1650556800000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6500384144856320",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "问题",
"archNo" : "0022-JS0000-TODO.-TODO-027",
"archTypeCode" : "JS0000",
"archTypeId" : "6485924961527040",
"archTypeName" : "建设项目",
"archivedDate" : 1587548214000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6502597485647104,
"id" : "6500384144856320",
"pageNum" : "1",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "hanfeixian",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650038400000,
"secretId" : "2",
"secretPeriodId" : 9,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000723",
"writingDate" : 1650038400000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503214760639744",
"_score" : 1.0,
"_source" : {
"annual" : "2020",
"archName" : "曹操出行-2行程单",
"archNo" : "0022-ZZ0100.TODO-03-006",
"archTypeCode" : "ZZ0100",
"archTypeId" : "6489894262050048",
"archTypeName" : "01 企业证照",
"archivedDate" : 1587699428000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503216857251072,
"id" : "6503214760639744",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "30年",
"savePeriodId" : "3",
"secret" : "核心商密",
"secretExpDate" : 1638633600000,
"secretId" : "3",
"secretPeriodId" : 1,
"sectId" : "6480626827621632",
"sectName" : "新奥集团股份有限公司",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000187",
"writingDate" : 1638633600000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503218290695424",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "消息接入规范",
"archNo" : "0022-ZZ0200.TODO-K093-002",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587709784000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 2,
"expDate" : 1619258366000,
"fileNo" : "",
"handlerId" : 6503218290752768,
"id" : "6503218290695424",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "核心商密",
"secretExpDate" : 1808560781000,
"secretId" : "3",
"secretPeriodId" : 7,
"sectId" : "6480626827621632",
"sectName" : "新奥集团股份有限公司",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000318",
"writingDate" : 1584547200000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503265140862208",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新奥档案系统-项目进度计划-20200408",
"archNo" : "0022-ZZ0200.TODO-null-010",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587711282000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503265140927744,
"id" : "6503265140862208",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "核心商密",
"secretExpDate" : 1649347200000,
"secretId" : "3",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000768",
"writingDate" : 1649347200000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503265140526336",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新奥档案系统-项目进度计划-20200415",
"archNo" : "0022-ZZ0200.TODO-null-011",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587711282000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503265411443968,
"id" : "6503265140526336",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650384000000,
"secretId" : "2",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000769",
"writingDate" : 1650384000000,
"year" : "2020"
}
}
]
}
}
实现archTypeId和year做聚合实现平级分组。
kibana:
POST ermsftrv1/_search
{
"aggs": {
"archTypeGroup": {
"terms": {
"field": "archTypeId.keyword",
"size": 10
}
},
"yearGroup": {
"terms": {
"field": "year.keyword",
"size": 10
}
}
}
}
结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 6,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6502586031240448",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新建文本文档",
"archNo" : "0022-SB0000.TODO-TODO-001",
"archTypeCode" : "SB0000",
"archTypeId" : "6485930821313792",
"archTypeName" : "设备仪器",
"archivedDate" : 1587545484000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6502586302145792,
"id" : "6502586031240448",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "hanfeixian",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650556800000,
"secretId" : "2",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000722",
"writingDate" : 1650556800000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6500384144856320",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "问题",
"archNo" : "0022-JS0000-TODO.-TODO-027",
"archTypeCode" : "JS0000",
"archTypeId" : "6485924961527040",
"archTypeName" : "建设项目",
"archivedDate" : 1587548214000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6502597485647104,
"id" : "6500384144856320",
"pageNum" : "1",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "hanfeixian",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650038400000,
"secretId" : "2",
"secretPeriodId" : 9,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000723",
"writingDate" : 1650038400000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503214760639744",
"_score" : 1.0,
"_source" : {
"annual" : "2020",
"archName" : "曹操出行-2行程单",
"archNo" : "0022-ZZ0100.TODO-03-006",
"archTypeCode" : "ZZ0100",
"archTypeId" : "6489894262050048",
"archTypeName" : "01 企业证照",
"archivedDate" : 1587699428000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503216857251072,
"id" : "6503214760639744",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "30年",
"savePeriodId" : "3",
"secret" : "核心商密",
"secretExpDate" : 1638633600000,
"secretId" : "3",
"secretPeriodId" : 1,
"sectId" : "6480626827621632",
"sectName" : "新奥集团股份有限公司",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000187",
"writingDate" : 1638633600000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503218290695424",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "消息接入规范",
"archNo" : "0022-ZZ0200.TODO-K093-002",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587709784000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 2,
"expDate" : 1619258366000,
"fileNo" : "",
"handlerId" : 6503218290752768,
"id" : "6503218290695424",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "核心商密",
"secretExpDate" : 1808560781000,
"secretId" : "3",
"secretPeriodId" : 7,
"sectId" : "6480626827621632",
"sectName" : "新奥集团股份有限公司",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000318",
"writingDate" : 1584547200000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503265140862208",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新奥档案系统-项目进度计划-20200408",
"archNo" : "0022-ZZ0200.TODO-null-010",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587711282000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503265140927744,
"id" : "6503265140862208",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "核心商密",
"secretExpDate" : 1649347200000,
"secretId" : "3",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000768",
"writingDate" : 1649347200000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503265140526336",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新奥档案系统-项目进度计划-20200415",
"archNo" : "0022-ZZ0200.TODO-null-011",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587711282000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503265411443968,
"id" : "6503265140526336",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650384000000,
"secretId" : "2",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000769",
"writingDate" : 1650384000000,
"year" : "2020"
}
}
]
},
"aggregations" : {
"yearGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "2020",
"doc_count" : 6
}
]
},
"archTypeGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "6495573858862336",
"doc_count" : 3
},
{
"key" : "6485924961527040",
"doc_count" : 1
},
{
"key" : "6485930821313792",
"doc_count" : 1
},
{
"key" : "6489894262050048",
"doc_count" : 1
}
]
}
}
}
java springboot实现:
SearchRequest searchRequest = new SearchRequest(ermsesProperties.getIndex());
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//第一个字段进行分组
TermsAggregationBuilder yearGroupAgg = AggregationBuilders.terms("yearGroup").field("year.keyword");
//根据第二个字段进行分组
TermsAggregationBuilder archTypeGroupAgg = AggregationBuilders.terms("archTypeGroup").field("archTypeId.keyword");
//如果存在第三个,以此类推...
//只需要平级添加聚合条件即可
sourceBuilder.aggregation(yearGroupAgg);
sourceBuilder.aggregation(archTypeGroupAgg);
searchRequest.source(sourceBuilder);
第二部、实现平级+层级分组聚合
实现archTypeId和year做聚合实现平级分组,同时实现archTypeId和secret层级聚合分组(也是百度中大篇幅的层级聚合分组)。
kibana:
POST ermsftrv1/_search
{
"aggs": {
"archTypeGroup": {
"terms": {
"field": "archTypeId.keyword",
"size": 10
},
"aggs": {
"secretGroup": {
"terms": {
"field": "secret.keyword"
}
}
}
},
"yearGroup": {
"terms": {
"field": "year.keyword",
"size": 10
}
}
}
}
结果:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 6,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6502586031240448",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新建文本文档",
"archNo" : "0022-SB0000.TODO-TODO-001",
"archTypeCode" : "SB0000",
"archTypeId" : "6485930821313792",
"archTypeName" : "设备仪器",
"archivedDate" : 1587545484000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6502586302145792,
"id" : "6502586031240448",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "hanfeixian",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650556800000,
"secretId" : "2",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000722",
"writingDate" : 1650556800000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6500384144856320",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "问题",
"archNo" : "0022-JS0000-TODO.-TODO-027",
"archTypeCode" : "JS0000",
"archTypeId" : "6485924961527040",
"archTypeName" : "建设项目",
"archivedDate" : 1587548214000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6502597485647104,
"id" : "6500384144856320",
"pageNum" : "1",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "hanfeixian",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650038400000,
"secretId" : "2",
"secretPeriodId" : 9,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000723",
"writingDate" : 1650038400000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503214760639744",
"_score" : 1.0,
"_source" : {
"annual" : "2020",
"archName" : "曹操出行-2行程单",
"archNo" : "0022-ZZ0100.TODO-03-006",
"archTypeCode" : "ZZ0100",
"archTypeId" : "6489894262050048",
"archTypeName" : "01 企业证照",
"archivedDate" : 1587699428000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503216857251072,
"id" : "6503214760639744",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "30年",
"savePeriodId" : "3",
"secret" : "核心商密",
"secretExpDate" : 1638633600000,
"secretId" : "3",
"secretPeriodId" : 1,
"sectId" : "6480626827621632",
"sectName" : "新奥集团股份有限公司",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000187",
"writingDate" : 1638633600000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503218290695424",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "消息接入规范",
"archNo" : "0022-ZZ0200.TODO-K093-002",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587709784000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 2,
"expDate" : 1619258366000,
"fileNo" : "",
"handlerId" : 6503218290752768,
"id" : "6503218290695424",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "核心商密",
"secretExpDate" : 1808560781000,
"secretId" : "3",
"secretPeriodId" : 7,
"sectId" : "6480626827621632",
"sectName" : "新奥集团股份有限公司",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000318",
"writingDate" : 1584547200000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503265140862208",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新奥档案系统-项目进度计划-20200408",
"archNo" : "0022-ZZ0200.TODO-null-010",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587711282000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503265140927744,
"id" : "6503265140862208",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "核心商密",
"secretExpDate" : 1649347200000,
"secretId" : "3",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000768",
"writingDate" : 1649347200000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503265140526336",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新奥档案系统-项目进度计划-20200415",
"archNo" : "0022-ZZ0200.TODO-null-011",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587711282000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503265411443968,
"id" : "6503265140526336",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650384000000,
"secretId" : "2",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000769",
"writingDate" : 1650384000000,
"year" : "2020"
}
}
]
},
"aggregations" : {
"yearGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "2020",
"doc_count" : 6
}
]
},
"archTypeGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "6495573858862336",
"doc_count" : 3,
"secretGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "核心商密",
"doc_count" : 2
},
{
"key" : "普通商密",
"doc_count" : 1
}
]
}
},
{
"key" : "6485924961527040",
"doc_count" : 1,
"secretGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "普通商密",
"doc_count" : 1
}
]
}
},
{
"key" : "6485930821313792",
"doc_count" : 1,
"secretGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "普通商密",
"doc_count" : 1
}
]
}
},
{
"key" : "6489894262050048",
"doc_count" : 1,
"secretGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "核心商密",
"doc_count" : 1
}
]
}
}
]
}
}
}
java实现:
SearchRequest searchRequest = new SearchRequest(ermsesProperties.getIndex());
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//第一个字段进行分组
TermsAggregationBuilder yearGroupAgg = AggregationBuilders.terms("yearGroup").field("year.keyword");
//根据第二个字段进行分组
TermsAggregationBuilder archTypeGroupAgg = AggregationBuilders.terms("archTypeGroup").field("archTypeId.keyword");
//自己聚合分组,生命方式一样
TermsAggregationBuilder secretGroup = AggregationBuilders.terms("secretGroup").field("secret.keyword");
//只需要平级添加聚合条件即可
sourceBuilder.aggregation(yearGroupAgg);
//设置聚合分组时,同事设置子分组(子层级)
sourceBuilder.aggregation(archTypeGroupAgg.subAggregation(secretGroup));
searchRequest.source(sourceBuilder);
第三部、script实现多字段查询
实现archTypeId和year平级聚合分组,同事查询出archTypeId对应的中文名称archTypeName。其中#split#是自定义的。
kibana:
POST ermsftrv1/_search
{
"aggs": {
"archTypeGroup": {
"terms": {
"script": "doc['archTypeId.keyword'].value +'#split#'+ doc['archTypeName.keyword'].value",
"size": 10
}
},
"yearGroup": {
"terms": {
"field": "year.keyword",
"size": 10
}
}
}
}
结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 6,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6502586031240448",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新建文本文档",
"archNo" : "0022-SB0000.TODO-TODO-001",
"archTypeCode" : "SB0000",
"archTypeId" : "6485930821313792",
"archTypeName" : "设备仪器",
"archivedDate" : 1587545484000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6502586302145792,
"id" : "6502586031240448",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "hanfeixian",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650556800000,
"secretId" : "2",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000722",
"writingDate" : 1650556800000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6500384144856320",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "问题",
"archNo" : "0022-JS0000-TODO.-TODO-027",
"archTypeCode" : "JS0000",
"archTypeId" : "6485924961527040",
"archTypeName" : "建设项目",
"archivedDate" : 1587548214000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6502597485647104,
"id" : "6500384144856320",
"pageNum" : "1",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "hanfeixian",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650038400000,
"secretId" : "2",
"secretPeriodId" : 9,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000723",
"writingDate" : 1650038400000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503214760639744",
"_score" : 1.0,
"_source" : {
"annual" : "2020",
"archName" : "曹操出行-2行程单",
"archNo" : "0022-ZZ0100.TODO-03-006",
"archTypeCode" : "ZZ0100",
"archTypeId" : "6489894262050048",
"archTypeName" : "01 企业证照",
"archivedDate" : 1587699428000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503216857251072,
"id" : "6503214760639744",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "30年",
"savePeriodId" : "3",
"secret" : "核心商密",
"secretExpDate" : 1638633600000,
"secretId" : "3",
"secretPeriodId" : 1,
"sectId" : "6480626827621632",
"sectName" : "新奥集团股份有限公司",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000187",
"writingDate" : 1638633600000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503218290695424",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "消息接入规范",
"archNo" : "0022-ZZ0200.TODO-K093-002",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587709784000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 2,
"expDate" : 1619258366000,
"fileNo" : "",
"handlerId" : 6503218290752768,
"id" : "6503218290695424",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "核心商密",
"secretExpDate" : 1808560781000,
"secretId" : "3",
"secretPeriodId" : 7,
"sectId" : "6480626827621632",
"sectName" : "新奥集团股份有限公司",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000318",
"writingDate" : 1584547200000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503265140862208",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新奥档案系统-项目进度计划-20200408",
"archNo" : "0022-ZZ0200.TODO-null-010",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587711282000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503265140927744,
"id" : "6503265140862208",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "核心商密",
"secretExpDate" : 1649347200000,
"secretId" : "3",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000768",
"writingDate" : 1649347200000,
"year" : "2020"
}
},
{
"_index" : "ermsftrv1",
"_type" : "_doc",
"_id" : "6503265140526336",
"_score" : 1.0,
"_source" : {
"annual" : "",
"archName" : "新奥档案系统-项目进度计划-20200415",
"archNo" : "0022-ZZ0200.TODO-null-011",
"archTypeCode" : "ZZ0200",
"archTypeId" : "6495573858862336",
"archTypeName" : "02 领导证照",
"archivedDate" : 1587711282000,
"archivedDep" : "1753-11-11 00:00:00",
"archivedOperator" : "",
"documentPage" : 0,
"entityTypeId" : 1,
"expDate" : -6820704000000,
"fileNo" : "",
"handlerId" : 6503265411443968,
"id" : "6503265140526336",
"pageNum" : "0",
"picPage" : 0,
"responsibleDept" : "",
"responsibleOper" : "zhangjunk",
"savePeriod" : "永久",
"savePeriodId" : "1",
"secret" : "普通商密",
"secretExpDate" : 1650384000000,
"secretId" : "2",
"secretPeriodId" : 1,
"sectId" : "6480640146142464",
"sectName" : "新奥集团档案局",
"sectNo" : "A0022",
"thridId" : "A0022-2020-0000000769",
"writingDate" : 1650384000000,
"year" : "2020"
}
}
]
},
"aggregations" : {
"yearGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "2020",
"doc_count" : 6
}
]
},
"archTypeGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "6495573858862336#split#02 领导证照",
"doc_count" : 3
},
{
"key" : "6485924961527040#split#建设项目",
"doc_count" : 1
},
{
"key" : "6485930821313792#split#设备仪器",
"doc_count" : 1
},
{
"key" : "6489894262050048#split#01 企业证照",
"doc_count" : 1
}
]
}
}
}
java实现:
SearchRequest searchRequest = new SearchRequest(ermsesProperties.getIndex());
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//第一个字段进行分组
TermsAggregationBuilder yearGroupAgg = AggregationBuilders.terms("yearGroup").field("year.keyword");
//第二个字段进行分组,使用script方式拼接返回值,但是要保证archTypeId和archTypeName是一对一的
Script script = new Script("doc['archTypeId.keyword'].value +'#split#'+ doc['archTypeName.keyword'].value");
TermsAggregationBuilder archTypeGroupAgg = AggregationBuilders.terms("archTypeGroup").script(script);
//添加aggregation
sourceBuilder.aggregation(yearGroupAgg);
sourceBuilder.aggregation(archTypeGroupAgg);
searchRequest.source(sourceBuilder);
刚接触es,不熟悉,最新版本的教程也不多。实际上基本是通过kibana敲命令琢磨出来的。建议装一个kibana或者head来辅助自己熟悉es。
四、分词的字段做聚合
这种情况,先看常规做法。这里以archTypeCode2和archTypeName做平级聚合,但是archTypeName字段是分词字段。往下看:
kibana:
POST ermsftrv1/_search
{
"aggs": {
"archTypeGroup": {
"terms": {
"field": "archTypeCode2",
"size": 10
}
},
"yearGroup": {
"terms": {
"field": "archTypeName",
"size": 10
}
}
}
}
聚合结果:
"aggregations" : {
"yearGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 4,
"buckets" : [
{
"key" : "证照",
"doc_count" : 20
},
{
"key" : "01",
"doc_count" : 10
},
{
"key" : "企业",
"doc_count" : 10
},
{
"key" : "02",
"doc_count" : 9
},
{
"key" : "领导",
"doc_count" : 9
},
{
"key" : "仪器",
"doc_count" : 3
},
{
"key" : "类型",
"doc_count" : 3
},
{
"key" : "设备",
"doc_count" : 3
},
{
"key" : "声像",
"doc_count" : 2
},
{
"key" : "建设",
"doc_count" : 2
}
]
},
"archTypeGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "ZZ",
"doc_count" : 20
},
{
"key" : "SB",
"doc_count" : 3
},
{
"key" : "JS",
"doc_count" : 2
},
{
"key" : "SX",
"doc_count" : 2
}
]
}
}
archTypeName这个聚合出现了:证照、01....等,这些是被分词后的。所以结果并不理想,我们这样解决。
在设置mapping时,archTypeName字段这么设置即可,
"archTypeName" : {
"type" : "text",
"fields" : {
"raw" : {
"type" : "keyword" #如果不设置keyword索引在聚合时将会使用已分解后的词
}
},
"analyzer" : "ik_max_word",
"fielddata" : true
}
这样正常使用archTypeName还是分词搜索即可,当我们需要使用archTypeName.keyword时只需要写archTypeName.raw.keyword即可,
修改后的kibana:
POST ermsftrv1/_search
{
"aggs": {
"archTypeGroup": {
"terms": {
"field": "archTypeCode2",
"size": 10
}
},
"yearGroup": {
"terms": {
"field": "archTypeName.raw",
"size": 10
}
}
}
}
聚合结果:01 企业证照、设备仪器等既可以当做完整的词来聚合展示了。
"aggregations" : {
"yearGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "01 企业证照",
"doc_count" : 10
},
{
"key" : "02 领导证照",
"doc_count" : 9
},
{
"key" : "设备仪器",
"doc_count" : 3
},
{
"key" : "声像类型",
"doc_count" : 2
},
{
"key" : "建设项目",
"doc_count" : 2
},
{
"key" : "证照类型",
"doc_count" : 1
}
]
},
"archTypeGroup" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "ZZ",
"doc_count" : 20
},
{
"key" : "SB",
"doc_count" : 3
},
{
"key" : "JS",
"doc_count" : 2
},
{
"key" : "SX",
"doc_count" : 2
}
]
}
}
五、实践代码
献上最终版代码,其中有大部搜索情况下的java实现方式,可以参考。
//全文检索字段列表
private final String[] MULTI_MATCH_FILDS ={
"archName","archNo","archTypeCode","archivedDept","archTypeName","archivedYear","createUser","notes",
"reorganizeOper","responsibleOper","savePeriod","secret","sectName","sectNo","writingDate","writingYear",
"year","signatory"
};
//全文检索高亮字段列表
private final String[] MULTI_MATCH_HIGHLIGHT_FILDS ={
"archName","archNo","archTypeCode","archivedDept","archTypeName","archivedYear","createUser","notes",
"reorganizeOper","responsibleOper","savePeriod","secret","sectName","sectNo","writingDate","writingYear",
"year","signatory"
};
/**
* 全文mapping中会被分词,并且含有keyword的字段
*/
private final List<String> MULTI_MATCH_KEYWORD_FIELDS = Arrays.asList(
"archName", "archNo","archTypeCode","archTypeName","archivedDate","archivedDept",
"archivedOperator","savePeriod","secretId","sectName", "sectNo","ermsProjectNo",
"productNo", "factoryNumber","volumeHao","ERMS_META_DATA_METADATA_EMPLOYEE_NO",
"ermsProjectName","dossierName", "dossierArchivedDept","equipmentUse", "ERMS_META_DATA_METADATA_ENTERPRISE_NAME",
"ERMS_META_DATA_METADATA_FIRST_PARTY","ERMS_META_DATA_METADATA_SECOND_PARTY",
"ERMS_META_DATA_METADATA_THIRD_PARTY","ERMS_META_DATA_METADATA_CONTRACT_OBJECT","signatory"
);
/**
* bool查询的使用
* Bool查询对应Lucene中的BooleanQuery,它由一个或者多个子句组成,每个子句都有特定的类型
*
* must
* 返回的文档必须满足must子句的条件,并且参与计算分值
*
* filter
* 返回的文档必须满足filter子句的条件,但是不会像must一样,参与计算分值
*
* should
* 返回的文档可能满足should子句的条件.在一个bool查询中,如果没有must或者filter,有一个或者多个should子句,那么只要满足一个就可以返回.minimum_should_match参数定义了至少满足几个子句.
*
* must_not
* 返回的文档必须不满足定义的条件
*
* 如果一个查询既有filter又有should,那么至少包含一个should子句.
*
* bool查询也支持禁用协同计分选项disable_coord.一般计算分值的因素取决于所有的查询条件.
*
* bool查询也是采用more_matches_is_better的机制,因此满足must和should子句的文档将会合并起来计算分值.
*
* @param request
* @return
*/
@Override
public Map<String, Object> bindAdvancedQueryGrid(AdvancedQueryParam request) {
log.info("context:{}", Context.getCurrentUser());
log.info("查询参数::::{}",request);
Map resMap = new HashMap();
//必要参数校验
if(!request.getAdvanced() && StringUtils.isBlank(request.getKey())&&
StringUtils.isBlank(request.getQueryItem())){//不是高级搜索的时候需要穿key
resMap.put("errMsg","关键字不能为空");
resMap.put("errCode","-1");
return resMap;
}
SearchRequest searchRequest = new SearchRequest(ermsesProperties.getIndex());
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 高级搜索条件
if (request.getAdvanced()) {//高级搜索参数拼接
//添加范围
List<Integer> range = request.getRange();
if(ObjectUtils.isEmpty(range) || (!range.contains(3) && !range.contains(1)))return resMap;//没选范围返回空
if(range.size()==1){//档案库和预归档只选了一个库的话
if (range.contains(3)){//档案库
boolQueryBuilder.must(QueryBuilders.termQuery("archStatus",3));
}else if(range.contains(1)){//我要归档
boolQueryBuilder.must(QueryBuilders.termQuery("archStatus",1));
}
}
List<AdvancedCondition> advancedConditions = request.getAdvancedConditions();
for (AdvancedCondition condition:advancedConditions) {
//主要参数为空时跳过
if(StringUtils.isBlank(condition.getValue()) ||
StringUtils.isBlank(condition.getBelong()) ||
(("9".equals(condition.getBelong()) || "10".equals(condition.getBelong()))
&& StringUtils.isBlank(condition.getInput())))continue;
//如果包含标题内容,添加搜索key以便查询电子文件
if("archName".equals(condition.getValue()) && StringUtils.isBlank(request.getKey())){
request.setKey(condition.getInput());
}
//查询条件构建
QueryBuilder termQueryBuilder;
/**
* 条件关系
* { id: 1, label: '包含', value: '1' },
* { id: 2, label: '小于', value: '2' },
* { id: 3, label: '小于等于', value: '3' },
* { id: 4, label: '不等于', value: '4' },
* { id: 5, label: '等于', value: '5' },
* { id: 6, label: '大于', value: '6' },
* { id: 7, label: '大于等于', value: '7' },
* { id: 8, label: '不包含', value: '8' },
* { id: 9, label: '为空', value: '9' },
* { id: 10, label: '不为空', value: '10' },
* { id: 11, label: '以之结尾', value: '11' },
* { id: 12, label: '以之开头', value: '12' }
*/
switch (condition.getBelong()){
case "1":
termQueryBuilder = QueryBuilders.matchQuery(condition.getValue(), condition.getInput());
break;
case "2":
termQueryBuilder = QueryBuilders.rangeQuery(condition.getValue()).lt(condition.getInput());
break;
case "3":
termQueryBuilder = QueryBuilders.rangeQuery(condition.getValue()).lte(condition.getInput());
break;
case "4":
termQueryBuilder = boolQueryBuilder.mustNot(QueryBuilders.termQuery(condition.getValue(), condition.getInput()));
break;
case "5":
if(MULTI_MATCH_KEYWORD_FIELDS.contains(condition.getValue())){
termQueryBuilder = QueryBuilders.termQuery(condition.getValue()+".keyword", condition.getInput());
}else {
termQueryBuilder = QueryBuilders.termQuery(condition.getValue(), condition.getInput());
}
break;
case "6":
termQueryBuilder = QueryBuilders.rangeQuery(condition.getValue()).gt(condition.getInput());
break;
case "7":
termQueryBuilder = QueryBuilders.rangeQuery(condition.getValue()).gte(condition.getInput());
break;
case "8":
termQueryBuilder = boolQueryBuilder.mustNot(QueryBuilders.matchQuery(condition.getValue(), condition.getInput()));
break;
case "9":
termQueryBuilder = boolQueryBuilder.mustNot(QueryBuilders.existsQuery(condition.getValue()));
break;
case "10":
termQueryBuilder = QueryBuilders.existsQuery(condition.getValue());
break;
case "11"://? 匹配任意字符,* 匹配0个或多个字符
termQueryBuilder = QueryBuilders.wildcardQuery(condition.getValue(), "*"+condition.getInput());
break;
case "12":
termQueryBuilder = QueryBuilders.prefixQuery(condition.getValue(), condition.getInput());
break;
default:
continue;
}
if(StringUtils.isNotBlank(condition.getLogic()) && "2".equals(condition.getLogic())){//或
boolQueryBuilder.should(termQueryBuilder);
}else {//与
boolQueryBuilder.must(termQueryBuilder);
}
}
}else {
//全文检索只搜档案库
boolQueryBuilder.must(QueryBuilders.termQuery("archStatus",3));
//全文检索--模糊查询条件
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(request.getKey(),MULTI_MATCH_FILDS));//取消全文检索,改为单属性选择搜索
}
//检索中--输入条件--档号
if (!ObjectUtils.isEmpty(request.getArchNo())) {
boolQueryBuilder.must(QueryBuilders.matchQuery("archNo", request.getArchNo()));
}
//检索中--输入条件--档案名称
if (!ObjectUtils.isEmpty(request.getArchName())) {
boolQueryBuilder.must(QueryBuilders.matchQuery("archName", request.getArchName()));
}
//检索中--输入条件--归档时间
if (!ObjectUtils.isEmpty(request.getStartDate()) || !ObjectUtils.isEmpty(request.getEndDate())) {
Object start = request.getStartDate();
Object end = request.getEndDate();
boolQueryBuilder.must(QueryBuilders.rangeQuery("archivedDate").from(start+" 00:00:00.000").to(end+" 59:59:59.999"));
}
//检索中--分类条件--门类
if (!ObjectUtils.isEmpty(request.getArchTypeCode2())) {
boolQueryBuilder.must(QueryBuilders.termsQuery("archTypeCode2", request.getArchTypeCode2()));
}
//检索中--分类条件--全宗查询条件,非全库且有全宗id时
if (!ObjectUtils.isEmpty(request.getSectId())) {
boolQueryBuilder.must(QueryBuilders.termQuery("sectId", request.getSectId()));
}
//检索中--分类条件--保管期限查询条件
if (!ObjectUtils.isEmpty(request.getSavePeriodId())) {
boolQueryBuilder.must(QueryBuilders.termQuery("savePeriodId", request.getSavePeriodId()));
}
//检索中--分类条件--成文日期查询条件
if (!ObjectUtils.isEmpty(request.getWritingYear())) {
boolQueryBuilder.must(QueryBuilders.termQuery("writingYear", request.getWritingYear()));
}
//2.5是否聚合 //TODO
//加入聚合
if (request.getAggregation()) {
//成文年份聚合
TermsAggregationBuilder yearGroupAgg = AggregationBuilders.terms("writingYearGroup").field("writingYear");
sourceBuilder.aggregation(yearGroupAgg);
//门类、档案类型聚合
TermsAggregationBuilder archTypeCode2Agg = AggregationBuilders.terms("archTypeCode2Group").field("archTypeCode2");
sourceBuilder.aggregation(archTypeCode2Agg);
//全宗聚合
Script script = new Script("doc['sectId'].value +'#split#'+ doc['sectName.keyword'].value");
TermsAggregationBuilder archTypeGroupAgg = AggregationBuilders.terms("sectGroup").script(script);
sourceBuilder.aggregation(archTypeGroupAgg);
//保管期限聚合
TermsAggregationBuilder savePeriodAgg = AggregationBuilders.terms("savePeriodGroup").field("savePeriodId");
sourceBuilder.aggregation(savePeriodAgg);
}
// 设置分页
sourceBuilder.query(boolQueryBuilder);
Integer offSet = 0;
Integer limit = 10;
if (!ObjectUtils.isEmpty(request.getPage()) && !ObjectUtils.isEmpty(request.getSize())) {
Integer page = (Integer) request.getPage();
limit = (Integer) request.getSize();
offSet = (page - 1) * limit;
}
sourceBuilder.from(offSet);
sourceBuilder.size(limit);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//TODO 设置高亮
//添加检索条件
searchRequest.source(sourceBuilder);
//2.构建查询结果
try {
SearchResponse searchResponse = es.searchDocument(searchRequest);
if(searchResponse.status() != RestStatus.OK){
resMap.put("errMsg","查询数据失败");
resMap.put("errCode","-1");
return resMap;
}
SearchHits hits = searchResponse.getHits();
//2.1构建返回总数
Long count = hits.getTotalHits().value;
//2.2构建返回内容
ES_ARCHIVED_FORM_RESPONSE response = new ES_ARCHIVED_FORM_RESPONSE();
List<ESArchObject> list = new ArrayList<>();
//字段遮挡 -- 获取可见权限
final List<ErmsDigitalRights> ermsDigitalRights = digitalRightsService.getErmsDigitalRights();
Map<String, Set<String>> archTypeIdMap = ermsDigitalRights.stream()
.filter(r -> r.getErmsArchTypeId() != null)
.collect(Collectors.groupingBy(r -> String.valueOf(r.getErmsSectId()),
Collectors.mapping(r -> String.valueOf(r.getErmsArchTypeId()),
Collectors.toSet())));
for (SearchHit hit : hits.getHits()) {
ESArchObject esArchObject = JSON.parseObject(hit.getSourceAsString(), ESArchObject.class);
//字段遮挡 -- 替换遮挡属性
hiddenField(archTypeIdMap.get(esArchObject.getSectId()), esArchObject);
list.add(esArchObject);
}
response.setForms(list);
if (request.getAggregation()) {//构建聚合
Aggregations aggregations = searchResponse.getAggregations();
//构建成文年份分组
Terms yearGroup = aggregations.get("writingYearGroup");
if(!CollectionUtils.isEmpty(yearGroup.getBuckets())){
List<Map> years = new ArrayList<>();
for (Terms.Bucket bucket : yearGroup.getBuckets()) {
Map<String,Object> iterm = new HashMap<>();
putGroupIterm(bucket, iterm, bucket.getKeyAsString(), bucket.getKeyAsString());
years.add(iterm);
}
response.setWritingYearGroup(years);
}
//构建档案类型分组
Terms archTypeCode2Group = aggregations.get("archTypeCode2Group");
if(!CollectionUtils.isEmpty(archTypeCode2Group.getBuckets())){
List<Map> archTypeCode2s = new ArrayList<>();
for (Terms.Bucket bucket : archTypeCode2Group.getBuckets()) {
Map<String,Object> iterm = new HashMap<>();
putGroupIterm(bucket, iterm, bucket.getKeyAsString(), bucket.getKeyAsString());
archTypeCode2s.add(iterm);
}
response.setArchTypeCode2Group(archTypeCode2s);
}
//构建全宗分组
Terms sectGroup = aggregations.get("sectGroup");
if(!CollectionUtils.isEmpty(sectGroup.getBuckets())){
List<Map> sects = new ArrayList<>();
for (Terms.Bucket bucket : sectGroup.getBuckets()) {
if(StringUtils.isNotBlank(bucket.getKeyAsString()) && bucket.getKeyAsString().contains("#split#")){
String[] split = bucket.getKeyAsString().split("#split#");
Map<String,Object> iterm = new HashMap<>();
putGroupIterm(bucket, iterm, split[0], split[1]);
sects.add(iterm);
}
}
response.setSectGroup(sects);
}
//构建保管期限分组
Terms savePeriodGroup = aggregations.get("savePeriodGroup");
if(!CollectionUtils.isEmpty(savePeriodGroup.getBuckets())){
List<Map> savePeriods = new ArrayList<>();
for (Terms.Bucket bucket : savePeriodGroup.getBuckets()) {
Map<String,Object> iterm = new HashMap<>();
putGroupIterm(bucket, iterm, bucket.getKeyAsString(), bucket.getKeyAsString());
savePeriods.add(iterm);
}
response.setSavePeriodGroup(savePeriods);
}
//获取电子文件聚合
if (!request.getAdvanced() && StringUtils.isNotBlank(request.getKey())){
try {
ElectronicSearchParam param = new ElectronicSearchParam();
BeanUtils.copyProperties(param,request);
if(StringUtils.isNotBlank(param.getKey())){
response.setElectronicGroup(eleFacetSearchRest(param));//电子文件分类统计
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
//TODO 查询的同时 往 检索历史表存入检索的
/*if (!ObjectUtils.isEmpty(request.get("archName"))||!ObjectUtils.isEmpty(request.get("IDes"))||!ObjectUtils.isEmpty(request.get("archNo"))||!ObjectUtils.isEmpty(request.get("name"))|| !ObjectUtils.isEmpty(request.get("end"))||!ObjectUtils.isEmpty(request.get("start"))){
ERMSSearchHistory ermsSearchHistory=new ERMSSearchHistory();
// Context.getERMSSearchHistoryService().createSearchHistory(ermsSearchHistory,request,count);
}*/
//3.查询到的值封装并返回
response.setCount(count);
resMap.put("data", response);
} catch (IOException e) {
e.printStackTrace();
}
return resMap;
}
环境搭建可见:
docker swarm集群下部署elasticsearch7.6.2集群+kibana7.6.2+es-head+中文分词
linux Centos7 安裝搭建elasticsearch7.6.2+kibana7.6.2+中文分词7.6.2详解
gogogo!