查询操作
更新时间:2019-08-20
获取度量(Metric)
如下代码可以获取metric列表:
Plain Text
1// 获取Metric
2GetMetricsResponse response = tsdbClient.getMetrics();
3
4// 打印结果
5for(String metric : response.getMetrics()) {
6 System.out.println(metric);
7}
获取Field
如下代码可以获取Field列表:
Plain Text
1String METRIC = "metric";
2
3// 获取Field
4GetFieldsResponse response = tsdbClient.getFields(METRIC);
5
6// 打印结果
7for(Map.Entry<String, FieldInfo> entry : response.getFields().entrySet()) {
8 System.out.println(entry.getKey() + ":");
9 System.out.println("\t" + entry.getValue().getType());
10}
获取标签(Tag)
如下代码可以获取标签(Tag)列表:
Plain Text
1String METRIC = "cpu_idle"; // 设置需要获取tag的metric
2
3// 获取标签
4GetTagsResponse response = tsdbClient.getTags(METRIC);
5
6// 打印结果
7for(Map.Entry<String, List<String>> entry : response.getTags().entrySet()) {
8 System.out.println(entry.getKey() + ":");
9 for(String tagValue : entry.getValue()) {
10 System.out.println("\t" + tagValue);
11 }
12}
查询数据点
如下代码可以查询数据点:
Plain Text
1String metric = "wind";
2String field = "direction";
3
4// 构造查询对象
5List<Query> queries = Arrays.asList(new Query() // 创建Query对象
6 .withMetric(metric) // 设置metric
7 .withField(field) // 设置查询的域名,不设置表示查询默认域
8 .withFilters(new Filters() // 创建Filters对象
9 .withRelativeStart("2 hours ago")) // 设置相对的开始时间,这里设置为2小时前
10 .withLimit(100) // 设置返回数据点数目限制
11 .addAggregator(new Aggregator() // 创建Aggregator对象
12 .withName(TsdbConstants.AGGREGATOR_NAME_SUM) // 设置聚合函数为Sum
13 .withSampling("1 second"))); // 设置采样
14
15// 查询数据
16QueryDatapointsResponse response = tsdbClient.queryDatapoints(queries);
17
18// 打印结果
19for (Result result : response.getResults()) {
20 System.out.println("Result:");
21 for (Group group : result.getGroups()) {
22 System.out.println("\tGroup:");
23
24 for (GroupInfo groupInfo : group.getGroupInfos()) {
25 System.out.println("\t\tGroupInfo:");
26 System.out.println("\t\t\tName:" + groupInfo.getName());
27 }
28 System.out.println("\t\tTimeAndValue:");
29 try {
30 for (Group.TimeAndValue timeAndValue : group.getTimeAndValueList()) {
31 if (timeAndValue.isDouble()) {
32 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getDoubleValue() + "]");
33 } else if (timeAndValue.isLong()) {
34 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getLongValue() + "]");
35 } else {
36 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getStringValue() + "]");
37 }
38 }
39 } catch (IOException e) {
40 e.printStackTrace();
41 }
42 }
43}
多域查询数据点
如下代码可以查询数据点:
Plain Text
1tring metric = "wind";
2String field1 = "direction";
3String field2 = "speed";
4String tag = "city";
5
6// 构造查询对象
7List<String> fields = Arrays.asList(field1, field2);
8List<Query> queries = Arrays.asList(new Query() // 创建Query对象
9 .withMetric(metric) // 设置metric
10 .withFields(fields) // 设置查询的域名列表,不设置表示查询默认域,和field冲突
11 .withTags(Arrays.asList(tag)) // 设置查询的Tag列表,不设置表示不查询,
12 .withFilters(new Filters() // 创建Filters对象
13 .withRelativeStart("2 hours ago") // 设置相对的开始时间,这里设置为2小时前
14 .withRelativeEnd("1 second ago")) // 设置相对的结束时间,不设置则默认为到当前时间为止
15 .withLimit(100));
16
17// 查询数据,返回结果的顺序和请求的field顺序相同
18QueryDatapointsResponse response = tsdbClient.queryDatapoints(queries);
19
20// 打印结果
21for (Result result : response.getResults()) {
22 System.out.println("Result:");
23 for (Group group : result.getGroups()) {
24 System.out.println("\tGroup:");
25
26 for (GroupInfo groupInfo : group.getGroupInfos()) {
27 System.out.println("\t\tGroupInfo:");
28 System.out.println("\t\t\tName:" + groupInfo.getName());
29 }
30 System.out.println("\t\tTimeAndValues:");
31 try {
32 for (Group.TimeAndValue timeAndValue : group.getTimeAndValueList()) {
33 System.out.print("\t\t\t[" + timeAndValue.getTime());
34 for (int index = 0; index < fields.size(); index++) {
35 System.out.print(", ");
36 if (!timeAndValue.isNull(index)) {
37 if (timeAndValue.isDouble(index)) {
38 System.out.print(timeAndValue.getDoubleValue(index));
39 } else if (timeAndValue.isLong(index)) {
40 System.out.print(timeAndValue.getLongValue(index));
41 } else {
42 System.out.print(timeAndValue.getStringValue(index));
43
44 }
45 } else {
46 System.out.print("null");
47 }
48 }
49 System.out.println("]");
50 }
51 } catch (IOException e) {
52 e.printStackTrace();
53 }
54 }
55}
查询数据点和对应的tags
如下代码可以查询数据点的同时返回对应的tags信息:
Plain Text
1String metric = "wind";
2String field = "direction";
3String tagKey1 = "city";
4String tagKey2 = "province"; // 构造查询对象
5List<Query> queries = Arrays.asList(new Query() // 创建Query对象
6 .withMetric(metric) // 设置metric
7 .withField(field) // 设置查询的域名,不设置表示查询默认域
8 .withTags(Arrays.asList(tagKey1, tagKey2)) // 设置需要同时返回的tag key列表
9 .withFilters(new Filters() // 创建Filters对象
10 .withRelativeStart("2 hours ago")) // 设置相对的开始时间
11 .withLimit(100)); // 设置返回数据点数目限制
12
13
14// 查询数据
15QueryDatapointsResponse response = tsdbClient.queryDatapoints(queries);
16
17// 打印结果
18for (Result result : response.getResults()) {
19 System.out.println("Result:");
20 for (Group group : result.getGroups()) {
21 System.out.println("\tGroup:");
22
23 for (GroupInfo groupInfo : group.getGroupInfos()) {
24 System.out.println("\t\tGroupInfo:");
25 System.out.println("\t\t\tName:" + groupInfo.getName());
26 }
27 System.out.println("\t\tTimeAndValue:");
28 try {
29 for (Group.TimeAndValue timeAndValue : group.getTimeAndValueList()) {
30 // 打印的格式为 [时间,FIELD_VALUE,TAG_1_VALUE,TAG_2_VALUE]
31 if (timeAndValue.isDouble()) {
32 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getDoubleValue(0) + "," + timeAndValue.getStringValue(1) + "," + timeAndValue.getStringValue(2) + "]");
33 } else if (timeAndValue.isLong()) {
34 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getLongValue(0) + "," + timeAndValue.getStringValue(1) + "," + timeAndValue.getStringValue(2) + "]");
35 } else {
36 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getStringValue(0) + "," + timeAndValue.getStringValue(1) + "," + timeAndValue.getStringValue(2) + "]");
37 }
38 }
39 } catch (IOException e) {
40 e.printStackTrace();
41 }
42 }
43}
使用插值方式查询数据点
如下代码可以对数据点进行插值:
Plain Text
1String metric = "wind";
2String field = "direction";
3
4// 构造查询对象
5List<Query> queries = Arrays.asList(new Query() // 创建Query对象
6 .withMetric(metric) // 设置metric
7 .withField(field) // 设置查询的域名,不设置表示查询默认域
8 .withFilters(new Filters() // 创建Filters对象
9 .withRelativeStart("2 hours ago") // 设置相对的开始时间
10 .withRelativeEnd("1 second ago")) // 设置相对的结束时间,不设置则默认为到当前时间为止
11 .withFill(new Fill()
12 .withType(TsdbConstants.FILL_TYPE_LINEAR) // 设置插值类型,这里设置成线性插值
13 .withInterval("5 minutes") // 设置插值间隔
14 .withMaxWriteInterval("10 minutes"))); // 设置最大写入间隔
15
16// 查询数据
17QueryDatapointsResponse response = tsdbClient.queryDatapoints(queries);
18
19// 打印结果
20for (Result result : response.getResults()) {
21 System.out.println("Result:");
22 for (Group group : result.getGroups()) {
23 System.out.println("\tGroup:");
24
25 for (GroupInfo groupInfo : group.getGroupInfos()) {
26 System.out.println("\t\tGroupInfo:");
27 System.out.println("\t\t\tName:" + groupInfo.getName());
28 }
29 System.out.println("\t\tTimeAndValue:");
30 try {
31 for (Group.TimeAndValue timeAndValue : group.getTimeAndValueList()) {
32 if (timeAndValue.isDouble()) {
33 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getDoubleValue() + "]");
34 } else if (timeAndValue.isLong()) {
35 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getLongValue() + "]");
36 } else {
37 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getStringValue() + "]");
38 }
39 }
40 } catch (IOException e) {
41 e.printStackTrace();
42 }
43 }
44}
分页查询原始数据点
TSDB支持两种分页查询的方式,一种是marker + limit的方式,一种是offset + limit的方式。 marker + limit的方式通过marker能在索引层确定查询的起始位置,因此查询速度更快,查询成本消耗更少。 offset + limit的方式需要将查询执行完成后,才能找到结果集offset的位置,因此查询成本消耗相对较大。当offset值过大时,查询返回耗时可能变大。
如下代码为marker + limit的分页查询原始数据点:
Plain Text
1String metric = "wind";
2String field = "direction";
3
4// 构造查询对象
5Query query = new Query() // 创建Query对象
6 .withMetric(metric) // 设置metric
7 .withField(field) // 设置查询的域名,不设置表示查询默认域
8 .withFilters(new Filters() // 创建Filters对象
9 .withRelativeStart("1 week ago") // 设置相对的开始时间,这里设置为1周前
10 .withRelativeEnd("1 second ago")); // 设置相对的结束时间,不设置则默认为到当前时间为止
11
12while (true) {
13 // 查询数据
14 QueryDatapointsResponse response = tsdbClient.queryDatapoints(Arrays.asList(query));
15 // 打印结果
16 Result result = response.getResults().get(0);
17 System.out.println("Result:");
18 for (Group group : result.getGroups()) {
19 System.out.println("\tGroup:");
20 for (GroupInfo groupInfo : group.getGroupInfos()) {
21 System.out.println("\t\tGroupInfo:");
22 System.out.println("\t\t\tName:" + groupInfo.getName());
23 }
24 System.out.println("\t\tTimeAndValue:");
25 try {
26 for (Group.TimeAndValue timeAndValue : group.getTimeAndValueList()) {
27 if (timeAndValue.isDouble()) {
28 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getDoubleValue() + "]");
29 } else if (timeAndValue.isLong()) {
30 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getLongValue() + "]");
31 } else {
32 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getStringValue() + "]");
33 }
34 }
35 } catch (IOException e) {
36 e.printStackTrace();
37 }
38 }
39 // 如果没有下一页数据,则退出循环
40 if (!result.isTruncated()) {
41 break;
42 }
43 // 设置下一页数据的marker
44 query.setMarker(result.getNextMarker());
45}
如下是offset + limit的分页查询原始数据点:
Plain Text
1String metric = "wind";
2String field = "direction";
3int pageSize = 10;
4Query query = new Query() // 创建Query对象
5 .withMetric(metric) // 设置metric
6 .withField(field) // 设置查询的域名,不设置表示查询默认域
7 .withFilters(new Filters() // 创建Filters对象
8 .withRelativeStart("1 week ago") // 设置相对的开始时间,这里设置为1周前
9 .withRelativeEnd("1 second ago")) // 设置相对的结束时间,不设置则默认为到当前时间为止
10 .withLimit(pageSize) // 设置每页大小为10
11 .withOffset(0); // 查询第1页的数据
12QueryDatapointsResponse response = tsdbClient.queryDatapoints(Arrays.asList(query));
13
14// 查询第2页的数据
15query.setOffset(pageSize * 1);
16response = tsdbClient.queryDatapoints(Arrays.asList(query));
17
18// 查询第3页的数据
19query.setOffset(pageSize * 2);
20response = tsdbClient.queryDatapoints(Arrays.asList(query));
查询数据时使用标签过滤
示例代码如下:
Plain Text
1String metric = "wind";
2String field = "direction";
3
4// 构造查询对象
5List<Query> queries = Arrays.asList(new Query() // 创建Query对象
6 .withMetric(metric) // 设置metric
7 .withField(field) // 设置查询的域名,不设置表示查询默认域
8 .withFilters(new Filters() // 创建Filters对象
9 .withRelativeStart("2 hours ago") // 设置相对的开始时间,这里设置为2小时前
10 .withRelativeEnd("1 second ago") // 设置相对的结束时间,不设置则默认为到当前时间为止
11 .addTagFilter(new TagFilter() // 创建TagFilter对象
12 .withTag("tag1") // 设置要过滤的tagKey
13 .addNotIn("value2")))); // 设置不允许出现的tagValue。还可以设置允许出现的tagValue,或者设置like匹配。
14// 查询数据
15QueryDatapointsResponse response = tsdbClient.queryDatapoints(queries);
16
17// 打印结果
18for (Result result : response.getResults()) {
19 System.out.println("Result:");
20 for (Group group : result.getGroups()) {
21 System.out.println("\tGroup:");
22 System.out.println("\t\tTimeAndValue:");
23 try {
24 for (Group.TimeAndValue timeAndValue : group.getTimeAndValueList()) {
25 if (timeAndValue.isDouble()) {
26 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getDoubleValue() + "]");
27 } else if (timeAndValue.isLong()) {
28 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getLongValue() + "]");
29 } else {
30 System.out.println("\t\t\t[" + timeAndValue.getTime() + "," + timeAndValue.getStringValue() + "]");
31 }
32 }
33 } catch (IOException e) {
34 e.printStackTrace();
35 }
36 }
37}
Filters对象设置示例
Plain Text
1// 使用绝对时间
2Filters filters1 = new Filters()
3 .withAbsoluteStart(System.currentTimeMillis() - 5000)
4 .withAbsoluteEnd(System.currentTimeMillis() - 1000);
5
6// 添加Tags:逐个添加
7Filters filters2 = new Filters()
8 .withRelativeStart("5 minutes ago")
9 .withRelativeEnd("2 minutes ago")
10 .addTag("tagKey1", "tagValue1", "tagValue2")
11 .addTag("tagKey2", "tagValue1");
12
13// 添加Tags:通过map添加
14Map<String, List<String>> tags = new HashMap<String, List<String>>(); // 创建tags
15tags.put("tagKey1", Arrays.asList("tagValue1", "tagValue2")); // 添加tag
16tags.put("tagKey2", Arrays.asList("tagValue1")); // 添加tag
17Filters filters3 = new Filters()
18 .withRelativeStart("5 minutes ago")
19 .withRelativeEnd("2 minutes ago")
20 .withTags(tags);
按值过滤的设置示例
Plain Text
1// 对long型数据进行过滤,支持的比较符为 >,<,>=,<=,= 和 !=
2Filters filters1 = new Filters()
3 .withAbsoluteStart(System.currentTimeMillis() - 5000)
4 .withAbsoluteEnd(System.currentTimeMillis() - 1000)
5 .withValue(ValueFilter.createValueFilter(ValueFilter.LESS_OR_EQUAL, 100L)); // 过滤条件为 "<= 100"
6
7// 对double型数据进行过滤,支持的比较符为 >,<,>=,<=,= 和 !=
8Filters filters1 = new Filters()
9 .withAbsoluteStart(System.currentTimeMillis() - 5000)
10 .withAbsoluteEnd(System.currentTimeMillis() - 1000)
11 .withValue(ValueFilter.createValueFilter(ValueFilter.GREATER, 99.9)); // 过滤条件为 "> 99.9"
12
13// 对String型数据进行过滤,支持的比较符为 >,<,>=,<=,= 和 !=
14Filters filters1 = new Filters()
15 .withAbsoluteStart(System.currentTimeMillis() - 5000)
16 .withAbsoluteEnd(System.currentTimeMillis() - 1000)
17 .withValue(ValueFilter.createValueFilter(ValueFilter.EQUAL, "stringvalue")); // 过滤条件为 "= 'stringvalue'"
18
19// 将数据与标签tagKey1的值进行比较过滤,支持的比较符为 >,<,>=,<=,= 和 !=
20Filters filters1 = new Filters()
21 .withAbsoluteStart(System.currentTimeMillis() - 5000)
22 .withAbsoluteEnd(System.currentTimeMillis() - 1000)
23 .withValue(ValueFilter.createValueFilterOfTag(ValueFilter.EQUAL, "tagKey1")); // 过滤条件为 "= tagKey1"
24
25// 对所有多域数据使用统一value进行过滤,支持的比较符为 >,<,>=,<=,= 和 !=
26Filters filters1 = new Filters()
27 .withAbsoluteStart(System.currentTimeMillis() - 5000)
28 .withAbsoluteEnd(System.currentTimeMillis() - 1000)
29 .withValue(ValueFilter.createValueFilter(ValueFilter.LESS_OR_EQUAL, 100L)); // 过滤条件为 "<= 100"
30
31// 对多域数据使用不同的value进行过滤,支持的比较符为 >,<,>=,<=,= 和 !=
32FieldFilter fieldFilter1 = new FieldFilter("field1", ValueFilter.createValueFilter("<", 100L));
33FieldFilter fieldFilter2 = new FieldFilter("field2", ValueFilter.createValueFilter(">", 200L));
34Filters filters1 = new Filters()
35 .withAbsoluteStart(System.currentTimeMillis() - 5000)
36 .withAbsoluteEnd(System.currentTimeMillis() - 1000)
37 .withFields(Arrays.asList(fieldFilter1, fieldFilter2)); // 过滤条件为 "field1< 100 && field2 > 200"
38
查询涉及的对象
查询涉及到的对象包括:Query对象,Filters对象,GroupBy对象和Aggregator对象,关于对象的具体介绍,请参看API参考中的[查询data point](TSDB/API参考/数据API接口说明.md#查询data point)。
SQL查询接口
v0.10.32版本的SDK中,支持了sql的查询。示例如下:
Plain Text
1String METRIC = "wind";
2String FIELD = "direction";
3
4String sql = "select " + FIELD + " from " + METRIC;
5
6// 查询数据
7GetRowWithSqlResponse response = tsdbClient.getRowsWithSql(sql);
8
9// 打印表头
10for (Column column : response.getColumns()) {
11 System.out.print(column.getName() + "\t");
12}
13System.out.println();
14// 打印数据行
15for (List<Object> row : response.getRows()) {
16 for (Object item : row) {
17 System.out.print(item.toString() + "\t");
18 }
19 System.out.println();
20}