Fix MQE `top_n` global query. (#12163)
diff --git a/docs/en/api/metrics-query-expression.md b/docs/en/api/metrics-query-expression.md
index c1641e0..95a7d88 100644
--- a/docs/en/api/metrics-query-expression.md
+++ b/docs/en/api/metrics-query-expression.md
@@ -217,7 +217,15 @@
The different operators could impact the `ExpressionResultType`, please refer to the above table.
## TopN Operation
-TopN Operation takes an expression and performs TopN calculation on its results.
+TopN Operation takes an expression and performs calculation to get the TopN of Services/Instances/Endpoints.
+The result depends on the `entity` condition in the query.
+- Global TopN:
+ - The `entity` is empty.
+ - The result is the topN Services/Instances/Endpoints in the whole traffics.
+ - **Notice**: If query the Endpoints metric, the global candidate set could be huge, please use it carefully.
+- Service's Instances/Endpoints TopN:
+ - The `serviceName` in the `entity` is not empty.
+ - The result is the topN Instances/Endpoints of the service.
Expression:
```text
@@ -229,7 +237,8 @@
`order` is the order of the top results. The value of `order` can be `asc` or `des`.
For example:
-If we want to query the top 10 services with the highest `service_cpm` metric value, we can use the following expression:
+If we want to query the current service's top 10 instances with the highest `service_instance_cpm` metric value, we can use the following expression
+under specific service:
```text
top_n(service_instance_cpm, 10, des)
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index a82d5e0..e114bca 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -118,6 +118,7 @@
* Support DoubleValue,IntValue,BoolValue in OTEL metrics attributes.
* [Break Change] gGRPC metrics exporter unified the metric value type and support labeled metrics.
* Add component definition(ID=152) for `c3p0`(JDBC3 Connection and Statement Pooling).
+* Fix MQE `top_n` global query.
#### UI
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/AggregationQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/AggregationQueryService.java
index d4a26b0..bac6dfb 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/AggregationQueryService.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/AggregationQueryService.java
@@ -60,8 +60,11 @@
final String valueCName = ValueColumnMetadata.INSTANCE.getValueCName(condition.getName());
List<KeyValue> additionalConditions = null;
if (StringUtil.isNotEmpty(condition.getParentService())) {
+ if (condition.getNormal() == null) {
+ return Collections.emptyList();
+ }
additionalConditions = new ArrayList<>(1);
- final String serviceId = IDManager.ServiceID.buildId(condition.getParentService(), condition.isNormal());
+ final String serviceId = IDManager.ServiceID.buildId(condition.getParentService(), condition.getNormal());
additionalConditions.add(new KeyValue(InstanceTraffic.SERVICE_ID, serviceId));
}
final List<SelectedRecord> selectedRecords = getAggregationQueryDAO().sortMetrics(
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/RecordCondition.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/RecordCondition.java
index 45a71b1..eab7a1d 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/RecordCondition.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/RecordCondition.java
@@ -55,7 +55,7 @@
final Entity entity = new Entity();
entity.setScope(condition.getScope() == null ? Scope.Service : condition.getScope());
entity.setServiceName(condition.getParentService());
- entity.setNormal(condition.isNormal());
+ entity.setNormal(condition.getNormal());
this.parentEntity = entity;
}
this.topN = condition.getTopN();
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/TopNCondition.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/TopNCondition.java
index 38c2509..8ced87a 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/TopNCondition.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/TopNCondition.java
@@ -46,7 +46,7 @@
* Normal service is the service having installed agent or metrics reported directly. Unnormal service is
* conjectural service, usually detected by the agent.
*/
- private boolean normal;
+ private Boolean normal;
/**
* Indicate the metrics entity scope. Because this is a top list, don't need to set the Entity like the
* MetricsCondition. Only accept scope = {@link Scope#Service} {@link Scope#ServiceInstance} and {@link