|
@@ -1,6 +1,7 @@
|
|
|
package cn.reghao.tnb.search.app.es;
|
|
package cn.reghao.tnb.search.app.es;
|
|
|
|
|
|
|
|
-import cn.reghao.tnb.search.app.log.model.NginxLog;
|
|
|
|
|
|
|
+import cn.reghao.jutil.jdk.converter.DateTimeConverter;
|
|
|
|
|
+import cn.reghao.jutil.jdk.web.log.NginxLog;
|
|
|
import cn.reghao.tnb.search.app.model.po.VideoText;
|
|
import cn.reghao.tnb.search.app.model.po.VideoText;
|
|
|
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
|
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
|
|
import co.elastic.clients.elasticsearch._types.FieldValue;
|
|
import co.elastic.clients.elasticsearch._types.FieldValue;
|
|
@@ -17,6 +18,7 @@ import co.elastic.clients.elasticsearch.core.search.HitsMetadata;
|
|
|
import co.elastic.clients.elasticsearch.core.search.TotalHits;
|
|
import co.elastic.clients.elasticsearch.core.search.TotalHits;
|
|
|
import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation;
|
|
import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation;
|
|
|
import co.elastic.clients.json.JsonData;
|
|
import co.elastic.clients.json.JsonData;
|
|
|
|
|
+import co.elastic.clients.util.ObjectBuilder;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
@@ -24,6 +26,8 @@ import java.io.IOException;
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
|
+import java.util.TreeMap;
|
|
|
|
|
+import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -39,15 +43,19 @@ public class SearchService {
|
|
|
this.esClient = elasticService.getElasticsearchClient();
|
|
this.esClient = elasticService.getElasticsearchClient();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void searchOne(String indexName, String searchText) throws IOException {
|
|
|
|
|
|
|
+ public void search(String indexName, String fieldValue) throws IOException {
|
|
|
|
|
+ String fieldName = "name";
|
|
|
SearchResponse<NginxLog> searchResponse = esClient.search(s -> s
|
|
SearchResponse<NginxLog> searchResponse = esClient.search(s -> s
|
|
|
.index(indexName)
|
|
.index(indexName)
|
|
|
|
|
+ /*.sort(s1 -> s1.field(f -> f.field(fieldName).order(SortOrder.Asc)))
|
|
|
|
|
+ .scroll(s2 -> s2.offset(0))*/
|
|
|
|
|
+ .from(0)
|
|
|
|
|
+ .size(100)
|
|
|
// 搜索请求的查询部分(搜索请求也可以有其他组件,如聚合)
|
|
// 搜索请求的查询部分(搜索请求也可以有其他组件,如聚合)
|
|
|
.query(q -> q
|
|
.query(q -> q
|
|
|
// 在众多可用的查询变体中选择一个。我们在这里选择匹配查询(全文搜索)
|
|
// 在众多可用的查询变体中选择一个。我们在这里选择匹配查询(全文搜索)
|
|
|
- .match(t -> t
|
|
|
|
|
- .field("name")
|
|
|
|
|
- .query(searchText))), NginxLog.class);
|
|
|
|
|
|
|
+ .match(t -> t.field(fieldName).query(fieldValue))), NginxLog.class);
|
|
|
|
|
+
|
|
|
TotalHits total = searchResponse.hits().total();
|
|
TotalHits total = searchResponse.hits().total();
|
|
|
boolean isExactResult = total != null && total.relation() == TotalHitsRelation.Eq;
|
|
boolean isExactResult = total != null && total.relation() == TotalHitsRelation.Eq;
|
|
|
if (isExactResult) {
|
|
if (isExactResult) {
|
|
@@ -62,31 +70,43 @@ public class SearchService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public List<NginxLog> searchByPage(String indexName, int pn, String searchField, String searchText) throws IOException {
|
|
|
|
|
- int ps = 100;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 分页查询
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param
|
|
|
|
|
+ * @return
|
|
|
|
|
+ * @date 2025-12-25 15:54:34
|
|
|
|
|
+ */
|
|
|
|
|
+ public List<NginxLog> searchByPage(String indexName, int pageSize, int pageNumber,
|
|
|
|
|
+ String fieldName, String fieldValue) throws IOException {
|
|
|
String sortField = "timeIso8601";
|
|
String sortField = "timeIso8601";
|
|
|
Query query = RangeQuery.of(r -> r.field("age").gte(JsonData.of(8)))._toQuery();
|
|
Query query = RangeQuery.of(r -> r.field("age").gte(JsonData.of(8)))._toQuery();
|
|
|
Query query11 = getOrQuery();
|
|
Query query11 = getOrQuery();
|
|
|
Query query1 = getAndQuery();
|
|
Query query1 = getAndQuery();
|
|
|
- Query query12 = getTermQuery();
|
|
|
|
|
|
|
+ // 等值查询
|
|
|
|
|
+ Query termQuery = getTermQuery(fieldName, fieldValue);
|
|
|
|
|
|
|
|
- int start = (pn-1)*ps;
|
|
|
|
|
|
|
+ int start = (pageNumber-1)*pageSize;
|
|
|
SearchRequest searchRequest = SearchRequest.of(s -> s
|
|
SearchRequest searchRequest = SearchRequest.of(s -> s
|
|
|
.index(indexName)
|
|
.index(indexName)
|
|
|
- .query(query1)
|
|
|
|
|
|
|
+ .query(termQuery)
|
|
|
.from(start)
|
|
.from(start)
|
|
|
- .size(ps)
|
|
|
|
|
|
|
+ .size(pageSize)
|
|
|
// 按 id 字段降序排列
|
|
// 按 id 字段降序排列
|
|
|
.sort(f -> f.field(o -> o.field(sortField).order(SortOrder.Desc)))
|
|
.sort(f -> f.field(o -> o.field(sortField).order(SortOrder.Desc)))
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
SearchResponse<NginxLog> searchResponse = esClient.search(searchRequest, NginxLog.class);
|
|
SearchResponse<NginxLog> searchResponse = esClient.search(searchRequest, NginxLog.class);
|
|
|
- /*List<Hit<NginxLog>> hits = searchResponse.hits().hits();
|
|
|
|
|
- for (Hit<NginxLog> hit : hits) {
|
|
|
|
|
- NginxLog product = hit.source();
|
|
|
|
|
- log.info("search page result: {}", product);
|
|
|
|
|
- }*/
|
|
|
|
|
- return searchResponse.hits().hits().stream().map(Hit::source).collect(Collectors.toList());
|
|
|
|
|
|
|
+ HitsMetadata<NginxLog> hitsMetadata = searchResponse.hits();
|
|
|
|
|
+ //得到总数
|
|
|
|
|
+ TotalHits totalHits = hitsMetadata.total();
|
|
|
|
|
+ long total = totalHits.value();
|
|
|
|
|
+ Double maxScore = hitsMetadata.maxScore();
|
|
|
|
|
+ //拿到匹配的数据
|
|
|
|
|
+ List<Hit<NginxLog>> hits = hitsMetadata.hits();
|
|
|
|
|
+ //拿到_source中的数据
|
|
|
|
|
+ List<NginxLog> nginxLogs = hits.stream().map(Hit::source).collect(Collectors.toList());
|
|
|
|
|
+ return nginxLogs;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void searchAll(String indexName) throws IOException {
|
|
public void searchAll(String indexName) throws IOException {
|
|
@@ -142,48 +162,10 @@ public class SearchService {
|
|
|
System.out.println();
|
|
System.out.println();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void searchByField(String indexName, String fieldName, String fieldValue) throws IOException {
|
|
|
|
|
- SearchRequest request = SearchRequest.of(s -> s
|
|
|
|
|
- .index(indexName)
|
|
|
|
|
- .query(query -> query.match(match -> match.field(fieldName).query(fieldValue)))
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- SearchResponse<NginxLog> searchResponse = esClient.search(request, NginxLog.class);
|
|
|
|
|
- log.info("search result: {}", searchResponse);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void search(String index) throws IOException {
|
|
|
|
|
- String fieldName = "url";
|
|
|
|
|
- String fieldValue = "/api";
|
|
|
|
|
- // 构造查询条件
|
|
|
|
|
- SearchRequest searchRequest = SearchRequest.of(s -> s.index(index)
|
|
|
|
|
- /*.sort(s1 -> s1.field(f -> f.field(fieldName).order(SortOrder.Asc)))
|
|
|
|
|
- .scroll(s2 -> s2.offset(0))*/
|
|
|
|
|
- .from(0)
|
|
|
|
|
- .size(500)
|
|
|
|
|
- .query(q -> q.match(m -> m.field(fieldName).query(FieldValue.of(fieldValue))))
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- SearchResponse<NginxLog> searchResponse = esClient.search(searchRequest, NginxLog.class);
|
|
|
|
|
- HitsMetadata<NginxLog> hitsMetadata = searchResponse.hits();
|
|
|
|
|
- //得到总数
|
|
|
|
|
- TotalHits totalHits = hitsMetadata.total();
|
|
|
|
|
- Double maxScore = hitsMetadata.maxScore();
|
|
|
|
|
- //拿到匹配的数据
|
|
|
|
|
- List<Hit<NginxLog>> hits = hitsMetadata.hits();
|
|
|
|
|
- //拿到_source中的数据
|
|
|
|
|
- List<NginxLog> nginxLogs = hits.stream().map(Hit::source).collect(Collectors.toList());
|
|
|
|
|
-
|
|
|
|
|
- //最大分数
|
|
|
|
|
- System.out.println(searchResponse.maxScore());
|
|
|
|
|
- //分片数
|
|
|
|
|
- System.out.println(searchResponse.shards());
|
|
|
|
|
- //是否超时
|
|
|
|
|
- System.out.println(searchResponse.timedOut());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
public void search() throws IOException {
|
|
public void search() throws IOException {
|
|
|
- Query query = getExistsQuery();
|
|
|
|
|
|
|
+ // 判断字段是否存在
|
|
|
|
|
+ String fieldName = "host";
|
|
|
|
|
+ Query query = getExistsQuery(fieldName);
|
|
|
|
|
|
|
|
String index = "nginx_log";
|
|
String index = "nginx_log";
|
|
|
SearchRequest searchRequest = new SearchRequest.Builder()
|
|
SearchRequest searchRequest = new SearchRequest.Builder()
|
|
@@ -192,10 +174,11 @@ public class SearchService {
|
|
|
.build();
|
|
.build();
|
|
|
SearchResponse<NginxLog> searchResponse = esClient.search(searchRequest, NginxLog.class);
|
|
SearchResponse<NginxLog> searchResponse = esClient.search(searchRequest, NginxLog.class);
|
|
|
TotalHits totalHits = searchResponse.hits().total();
|
|
TotalHits totalHits = searchResponse.hits().total();
|
|
|
|
|
+ long total = totalHits.value();
|
|
|
List<NginxLog> list = searchResponse.hits().hits().stream().map(Hit::source).collect(Collectors.toList());
|
|
List<NginxLog> list = searchResponse.hits().hits().stream().map(Hit::source).collect(Collectors.toList());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void count(String index) throws IOException {
|
|
|
|
|
|
|
+ public long count(String index) throws IOException {
|
|
|
Query query1 = getMatchQuery();
|
|
Query query1 = getMatchQuery();
|
|
|
// remoteAddr 字段为空
|
|
// remoteAddr 字段为空
|
|
|
Query query2 = BoolQuery.of(b ->
|
|
Query query2 = BoolQuery.of(b ->
|
|
@@ -214,7 +197,7 @@ public class SearchService {
|
|
|
CountResponse countResponse = esClient.count(countRequest);
|
|
CountResponse countResponse = esClient.count(countRequest);
|
|
|
long total = countResponse.count();
|
|
long total = countResponse.count();
|
|
|
ShardStatistics shardStatistics = countResponse.shards();
|
|
ShardStatistics shardStatistics = countResponse.shards();
|
|
|
- System.out.println("total -> " + total);
|
|
|
|
|
|
|
+ return total;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -224,15 +207,13 @@ public class SearchService {
|
|
|
* @return
|
|
* @return
|
|
|
* @date 2025-03-12 13:45:17
|
|
* @date 2025-03-12 13:45:17
|
|
|
*/
|
|
*/
|
|
|
- public Query getTermQuery() {
|
|
|
|
|
|
|
+ public Query getTermQuery(String fieldName, String fieldValue) {
|
|
|
String fieldName1 = "url";
|
|
String fieldName1 = "url";
|
|
|
String fieldValue1 = "/datareceive/ReceiveData/SendContentResult\"";
|
|
String fieldValue1 = "/datareceive/ReceiveData/SendContentResult\"";
|
|
|
-
|
|
|
|
|
String fieldName2 = "requestMethod";
|
|
String fieldName2 = "requestMethod";
|
|
|
String fieldValue2 = "POST";
|
|
String fieldValue2 = "POST";
|
|
|
-
|
|
|
|
|
Query query = TermQuery.of(t -> t
|
|
Query query = TermQuery.of(t -> t
|
|
|
- .field(fieldName1).value(FieldValue.of(fieldValue1))
|
|
|
|
|
|
|
+ .field(fieldName).value(FieldValue.of(fieldValue))
|
|
|
)._toQuery();
|
|
)._toQuery();
|
|
|
return query;
|
|
return query;
|
|
|
}
|
|
}
|
|
@@ -322,9 +303,9 @@ public class SearchService {
|
|
|
* @return
|
|
* @return
|
|
|
* @date 2025-03-12 14:20:26
|
|
* @date 2025-03-12 14:20:26
|
|
|
*/
|
|
*/
|
|
|
- public Query getExistsQuery() {
|
|
|
|
|
|
|
+ public Query getExistsQuery(String fieldName) {
|
|
|
// 判断字段是否存在
|
|
// 判断字段是否存在
|
|
|
- Query query = ExistsQuery.of(t -> t.field("host"))._toQuery();
|
|
|
|
|
|
|
+ Query query = ExistsQuery.of(t -> t.field(fieldName))._toQuery();
|
|
|
return query;
|
|
return query;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -356,14 +337,16 @@ public class SearchService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public Query getQuery() {
|
|
public Query getQuery() {
|
|
|
- MatchAllQuery.of(m -> m.queryName("host"))._toQuery();
|
|
|
|
|
|
|
+ Query query1 = MatchAllQuery.of(m -> m.queryName("host"))._toQuery();
|
|
|
|
|
+
|
|
|
// 一般情况下有一个单词错误的情况下,fuzzy 查询可以找到另一个近似的词来代替,主要有以下场景:
|
|
// 一般情况下有一个单词错误的情况下,fuzzy 查询可以找到另一个近似的词来代替,主要有以下场景:
|
|
|
//
|
|
//
|
|
|
//修改一个单词,如:box--->fox。
|
|
//修改一个单词,如:box--->fox。
|
|
|
//移除一个单词,如:black-->lack。
|
|
//移除一个单词,如:black-->lack。
|
|
|
//插入一个单词,如:sic-->sick。
|
|
//插入一个单词,如:sic-->sick。
|
|
|
//转换两个单词顺序,如:act-->cat。
|
|
//转换两个单词顺序,如:act-->cat。
|
|
|
- FuzzyQuery.of(f -> f.field("host").value("lonel"));
|
|
|
|
|
|
|
+ Query query2 = FuzzyQuery.of(f -> f.field("host").value("lonel"))._toQuery();
|
|
|
|
|
+
|
|
|
// 通过指定字段的前缀进行查询
|
|
// 通过指定字段的前缀进行查询
|
|
|
Query query = PrefixQuery.of(p -> p.field("host").value("api"))._toQuery();
|
|
Query query = PrefixQuery.of(p -> p.field("host").value("api"))._toQuery();
|
|
|
return query;
|
|
return query;
|
|
@@ -376,21 +359,37 @@ public class SearchService {
|
|
|
* @return
|
|
* @return
|
|
|
* @date 2025-03-12 15:06:48
|
|
* @date 2025-03-12 15:06:48
|
|
|
*/
|
|
*/
|
|
|
- public void aggregate(String index) throws Exception {
|
|
|
|
|
|
|
+ public void aggregate(String index, String aggregateField) throws Exception {
|
|
|
String aggField1 = "status";
|
|
String aggField1 = "status";
|
|
|
String aggField2 = "remoteAddr";
|
|
String aggField2 = "remoteAddr";
|
|
|
String aggField3 = "httpUserAgent.raw";
|
|
String aggField3 = "httpUserAgent.raw";
|
|
|
String aggField4 = "url.raw";
|
|
String aggField4 = "url.raw";
|
|
|
String aggField5 = "timeIso8601";
|
|
String aggField5 = "timeIso8601";
|
|
|
|
|
|
|
|
- String fieldName1 = "url.raw";
|
|
|
|
|
- String fieldValue1 = "/base/Device/PageList";
|
|
|
|
|
|
|
+ String fieldName = "url.raw";
|
|
|
|
|
+ String fieldValue = "/datareceive/ReceiveData/SendContentResult";
|
|
|
|
|
|
|
|
SearchRequest searchRequest = new SearchRequest.Builder()
|
|
SearchRequest searchRequest = new SearchRequest.Builder()
|
|
|
.index(index)
|
|
.index(index)
|
|
|
- .query(q -> q.bool(b -> b.must(m -> m.term(t -> t.field(fieldName1).value(FieldValue.of(fieldValue1))))))
|
|
|
|
|
- .size(10000)
|
|
|
|
|
- .aggregations("first_agg", a->a.terms(t->t.field(aggField5).size(65535)))
|
|
|
|
|
|
|
+ .size(0)
|
|
|
|
|
+ .query(q -> q.bool(b -> b.must(m -> m.term(t -> t.field(fieldName).value(FieldValue.of(fieldValue))))))
|
|
|
|
|
+ //.aggregations("first_agg", a->a.terms(t->t.field(aggregateField).size(65535)))
|
|
|
|
|
+ /*.aggregations("agg1", a -> a.dateRange(t -> t.field(aggField5).format("yyyy-MM-dd HH:mm:ss")
|
|
|
|
|
+ .ranges(r -> r.from(new Function<>() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public ObjectBuilder<FieldDateMath> apply(FieldDateMath.Builder builder) {
|
|
|
|
|
+ return builder.expr("2023-11-20 00:00:00");
|
|
|
|
|
+ }
|
|
|
|
|
+ }).to(new Function<>() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public ObjectBuilder<FieldDateMath> apply(FieldDateMath.Builder builder) {
|
|
|
|
|
+ return builder.expr("2023-11-20 23:59:59");
|
|
|
|
|
+ }
|
|
|
|
|
+ }))))*/
|
|
|
|
|
+ //
|
|
|
|
|
+ //.size(0)
|
|
|
|
|
+ // 按天进行聚合
|
|
|
|
|
+ .aggregations("agg1", a->a.dateHistogram(t->t.field(aggregateField).calendarInterval(CalendarInterval.Day).minDocCount(0)))
|
|
|
//.aggregations("agg1", a->a.histogram(t->t.field("httpUserAgent").interval(50.0)))
|
|
//.aggregations("agg1", a->a.histogram(t->t.field("httpUserAgent").interval(50.0)))
|
|
|
//.aggregations("agg1", a->a.sum(t->t.field("httpUserAgent")))
|
|
//.aggregations("agg1", a->a.sum(t->t.field("httpUserAgent")))
|
|
|
//.aggregations("second_agg", a->a.avg(t->t.field("status")))
|
|
//.aggregations("second_agg", a->a.avg(t->t.field("status")))
|
|
@@ -398,37 +397,131 @@ public class SearchService {
|
|
|
|
|
|
|
|
SearchResponse<NginxLog> searchResponse = esClient.search(searchRequest, NginxLog.class);
|
|
SearchResponse<NginxLog> searchResponse = esClient.search(searchRequest, NginxLog.class);
|
|
|
TotalHits totalHits = searchResponse.hits().total();
|
|
TotalHits totalHits = searchResponse.hits().total();
|
|
|
|
|
+ long total = totalHits.value();
|
|
|
Map<String, Aggregate> resultMap = searchResponse.aggregations();
|
|
Map<String, Aggregate> resultMap = searchResponse.aggregations();
|
|
|
|
|
|
|
|
- List<Long> countList = new ArrayList<>();
|
|
|
|
|
|
|
+ Map<Long, Long> map = new TreeMap<>();
|
|
|
resultMap.forEach((k, v) -> {
|
|
resultMap.forEach((k, v) -> {
|
|
|
Object value = v._get();
|
|
Object value = v._get();
|
|
|
- if (value instanceof StringTermsAggregate) {
|
|
|
|
|
- StringTermsAggregate terms = (StringTermsAggregate) value;
|
|
|
|
|
|
|
+ if (value instanceof StringTermsAggregate terms) {
|
|
|
List<StringTermsBucket> list = terms.buckets().array();
|
|
List<StringTermsBucket> list = terms.buckets().array();
|
|
|
list.forEach(bucket -> {
|
|
list.forEach(bucket -> {
|
|
|
String groupKey = (String) bucket.key()._get();
|
|
String groupKey = (String) bucket.key()._get();
|
|
|
long count = bucket.docCount();
|
|
long count = bucket.docCount();
|
|
|
- countList.add(count);
|
|
|
|
|
//System.out.println(groupKey + " : " + IpTool.getLocation(groupKey) + " -> " + count);
|
|
//System.out.println(groupKey + " : " + IpTool.getLocation(groupKey) + " -> " + count);
|
|
|
- System.out.println(groupKey + " : " + count);
|
|
|
|
|
|
|
+ System.out.printf("%s -> %s\n", groupKey, count);
|
|
|
});
|
|
});
|
|
|
System.out.println("bucket size = " + list.size());
|
|
System.out.println("bucket size = " + list.size());
|
|
|
- } else if (value instanceof LongTermsAggregate) {
|
|
|
|
|
- LongTermsAggregate terms = (LongTermsAggregate) value;
|
|
|
|
|
|
|
+ } else if (value instanceof LongTermsAggregate terms) {
|
|
|
List<LongTermsBucket> list = terms.buckets().array();
|
|
List<LongTermsBucket> list = terms.buckets().array();
|
|
|
list.forEach(bucket -> {
|
|
list.forEach(bucket -> {
|
|
|
String groupKey = bucket.key();
|
|
String groupKey = bucket.key();
|
|
|
- String groupKeyStr = bucket.keyAsString();
|
|
|
|
|
|
|
+ Long secondTimestamp = Long.parseLong(groupKey)/1000;
|
|
|
|
|
+ //String groupKeyStr = bucket.keyAsString();
|
|
|
|
|
+ String dateTimeStr = DateTimeConverter.format(Long.parseLong(groupKey));
|
|
|
|
|
+ long count = bucket.docCount();
|
|
|
|
|
+ map.put(secondTimestamp, count);
|
|
|
|
|
+ System.out.printf("%s -> %s\n", dateTimeStr, count);
|
|
|
|
|
+ });
|
|
|
|
|
+ } else if (value instanceof DateRangeAggregate aggregate) {
|
|
|
|
|
+ List<RangeBucket> list = aggregate.buckets().array();
|
|
|
|
|
+ list.forEach(rangeBucket -> {
|
|
|
|
|
+ String key = rangeBucket.key();
|
|
|
|
|
+ System.out.println(rangeBucket);
|
|
|
|
|
+ });
|
|
|
|
|
+ } else if (value instanceof DateHistogramAggregate aggregate) {
|
|
|
|
|
+ List<DateHistogramBucket> list = aggregate.buckets().array();
|
|
|
|
|
+ list.forEach(rangeBucket -> {
|
|
|
|
|
+ long msTimestamp = Long.parseLong(rangeBucket.key());
|
|
|
|
|
+ String dateStr = DateTimeConverter.localDateTime(msTimestamp).toLocalDate().toString();
|
|
|
|
|
+ long count = rangeBucket.docCount();
|
|
|
|
|
+ System.out.printf("%s -> %s\n", dateStr, count);
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ System.out.println(value);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据天进行聚合
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param
|
|
|
|
|
+ * @return 日期 -> 每日访问量
|
|
|
|
|
+ * @date 2025-12-25 17:23:04
|
|
|
|
|
+ */
|
|
|
|
|
+ public Map<String, Long> aggregateByDay(String index, String dateField) throws Exception {
|
|
|
|
|
+ SearchRequest searchRequest = new SearchRequest.Builder()
|
|
|
|
|
+ .index(index)
|
|
|
|
|
+ .size(0)
|
|
|
|
|
+ // 按天进行聚合
|
|
|
|
|
+ .aggregations("agg1", a->a.dateHistogram(t->t.field(dateField).calendarInterval(CalendarInterval.Day).minDocCount(0)))
|
|
|
|
|
+ .build();
|
|
|
|
|
+
|
|
|
|
|
+ SearchResponse<NginxLog> searchResponse = esClient.search(searchRequest, NginxLog.class);
|
|
|
|
|
+ TotalHits totalHits = searchResponse.hits().total();
|
|
|
|
|
+ long total = totalHits.value();
|
|
|
|
|
+ Map<String, Aggregate> resultMap = searchResponse.aggregations();
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, Long> map = new TreeMap<>();
|
|
|
|
|
+ resultMap.forEach((k, v) -> {
|
|
|
|
|
+ Object value = v._get();
|
|
|
|
|
+ if (value instanceof DateHistogramAggregate aggregate) {
|
|
|
|
|
+ List<DateHistogramBucket> list = aggregate.buckets().array();
|
|
|
|
|
+ list.forEach(rangeBucket -> {
|
|
|
|
|
+ long msTimestamp = Long.parseLong(rangeBucket.key());
|
|
|
|
|
+ String dateStr = DateTimeConverter.localDateTime(msTimestamp).toLocalDate().toString();
|
|
|
|
|
+ long count = rangeBucket.docCount();
|
|
|
|
|
+ map.put(dateStr, count);
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ System.out.println("unknown aggregate type: " + value.getClass().getName());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return map;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 在指定日期里对 url 进行聚合
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param
|
|
|
|
|
+ * @return url -> 每日访问量
|
|
|
|
|
+ * @date 2025-12-25 17:31:56
|
|
|
|
|
+ */
|
|
|
|
|
+ public Map<String, Long> aggregateByUrl(String index, String urlField,
|
|
|
|
|
+ String dateField, String dateValue) throws Exception {
|
|
|
|
|
+ String start = String.format("%sT00:00:00Z", dateValue);
|
|
|
|
|
+ String end = String.format("%sT23:59:59Z", dateValue);
|
|
|
|
|
+ SearchRequest searchRequest = new SearchRequest.Builder()
|
|
|
|
|
+ .index(index)
|
|
|
|
|
+ .size(0)
|
|
|
|
|
+ .query(q -> q.range(r -> r.field(dateField).gte(JsonData.of(start)).lte(JsonData.of(end))))
|
|
|
|
|
+ .aggregations("first_agg", a->a.terms(t->t.field(urlField).size(65535)))
|
|
|
|
|
+ .build();
|
|
|
|
|
+
|
|
|
|
|
+ SearchResponse<NginxLog> searchResponse = esClient.search(searchRequest, NginxLog.class);
|
|
|
|
|
+ TotalHits totalHits = searchResponse.hits().total();
|
|
|
|
|
+ long total = totalHits.value();
|
|
|
|
|
+ Map<String, Aggregate> resultMap = searchResponse.aggregations();
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, Long> map = new TreeMap<>();
|
|
|
|
|
+ resultMap.forEach((k, v) -> {
|
|
|
|
|
+ Object value = v._get();
|
|
|
|
|
+ if (value instanceof StringTermsAggregate terms) {
|
|
|
|
|
+ List<StringTermsBucket> list = terms.buckets().array();
|
|
|
|
|
+ list.forEach(bucket -> {
|
|
|
|
|
+ String groupKey = (String) bucket.key()._get();
|
|
|
long count = bucket.docCount();
|
|
long count = bucket.docCount();
|
|
|
- countList.add(count);
|
|
|
|
|
- System.out.println(groupKeyStr + " : " + count);
|
|
|
|
|
|
|
+ //System.out.println(groupKey + " : " + IpTool.getLocation(groupKey) + " -> " + count);
|
|
|
|
|
+ // System.out.printf("%s -> %s\n", groupKey, count);
|
|
|
|
|
+ map.put(groupKey, count);
|
|
|
});
|
|
});
|
|
|
} else {
|
|
} else {
|
|
|
System.out.println(value);
|
|
System.out.println(value);
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- System.out.println("total = " + countList.stream().mapToLong(Long::longValue).sum());
|
|
|
|
|
|
|
+ return map;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|