Druid學習之查詢語法
寫在前面
最近一段時間都在做druid實時資料查詢的工作,本文簡單將官網上的英文文件加上自己的理解翻譯成中文,同時將自己遇到的問題及解決方法list下,防止遺忘。
本文的demo示例均來源於官網。
Druid查詢概述
Druid的查詢是使用Rest風格的http請求查詢服務節點,客戶端通過傳送Json物件請求查詢介面。可以使用shell指令碼查詢或通過Google的ARC外掛構造Post請求進行查詢。
Query構建
Shell指令碼
curl -X POST '<queryable_host>:<port>/druid/v2/?pretty' -H 'Content-Type:application/json' -d @<query_json_file>
其中<queryable_host>:<port>為broker、historical或realtime程序所在機器的ip和提供服務的埠,query_json_file為json配置檔案路徑。
ARC外掛
見下圖
Druid查詢
1 Druid查詢型別
不同的查詢場景使用不同的查詢方式。Druid有很多查詢型別,對於各種型別的查詢型別的配置可以通過配置不同的Query實現。Druid的查詢型別,概括為以下3類:
1.聚合查詢:時間序列查詢(Timeseroes),Top查詢(TopN),GroupBy查詢(GroupBy) 2.元資料查詢:時間範圍(Time Boundary),段元資料(Segment Metadata),資料來源(DataSource) 2.Search查詢(Search)
一般聚合查詢使用的較多,其他型別的查詢方式使用場景較少且較簡單,可直接參考官網給出的demo即可查詢;本文主要介紹聚合查詢。一般情況下,Timeseries和TopN查詢效能優於GroupBy,GroupBy查詢方式最靈活但是最耗效能。Timeseries查詢效能明顯優於GroupBy,因為聚合不需要其他GroupBy其他維度;對於Groupby和排序在一個單一維度的場景,TopN優於GroupBy。
2 Druid主要查詢屬性簡介
一條Druid query中主要包含以下幾種屬性:
1.queryType:查詢型別,即timeseries,topN,groupBy等; 2.dataSource:資料來源,類似Mysql中的表的概念; 3.granularity:聚合粒度,聚合粒度有none,all,week,day,hour等; 4.filter:過濾條件,類似Mysql中的where條件; 5.aggregator:聚合方式,類似Mysql中的count,sum等操作
2.1.1 簡單的聚合粒度
簡單的聚合粒度有:all、none、second、minute、fifteen_minute、thirty_minute、hour、day、week、month、quarter、year;簡單聚合粒度的查詢取決於druid儲存資料的最小粒度,如果構建資料的最小粒度是小時,使用minute粒度去查詢,結果資料也是小時粒度的資料。
假設儲存在Druid中的資料使用毫秒粒度構建,資料格式如下:
{"timestamp": "2013-08-31T01:02:33Z", "page": "AAA", "language" : "en"} {"timestamp": "2013-09-01T01:02:33Z", "page": "BBB", "language" : "en"} {"timestamp": "2013-09-02T23:32:45Z", "page": "CCC", "language" : "en"} {"timestamp": "2013-09-03T03:32:45Z", "page": "DDD", "language" : "en"}
提交一個小時粒度的groupBy查詢,查詢query如下:
{
"queryType":"groupBy",
"dataSource":"my_dataSource",
"granularity":"hour",
"dimensions":[
"language"
],
"aggregations":[
{
"type":"count",
"name":"count"
}
],
"intervals":[
"2000-01-01T00:00Z/3000-01-01T00:00Z"
]
}
按小時粒度進行的groupby查詢結果中timestamp值精確到小時,比小時粒度更小粒度值自動補填零,以此類推按天查詢,則小時及小粒度補零。timestamp值為UTC。查詢結果如下:
[ {
"version" : "v1",
"timestamp" : "2013-08-31T01:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-01T01:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T23:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-03T03:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
} ]
如若指定聚合粒度為day,則按照天為單位對資料進行聚合,查詢結果如下:
[ {
"version" : "v1",
"timestamp" : "2013-08-31T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-01T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-03T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
} ]
如若聚合粒度設定為none,則按照druid中build資料的最小粒度查詢資料,即不進行聚合,如bulid資料的粒度是ms,則聚合出來的結果也是毫秒:
[ {
"version" : "v1",
"timestamp" : "2013-08-31T01:02:33.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-01T01:02:33.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T23:32:45.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-03T03:32:45.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
} ]
如若將聚合粒度設定為all,則返回資料的長度為1,即把查詢時間段的資料做一個彙總:
[ {
"version" : "v1",
"timestamp" : "2000-01-01T00:00:00.000Z",
"event" : {
"count" : 4,
"language" : "en"
}
} ]
2.1.2 時間聚合粒度
可指定一定的時間段進行聚合,返回UTC時間;支援可選屬性origin;不指定時間,預設的開始時間=1970-01-01T00:00:00Z;
持續時間段2小時,從1970-01-01T00:00:00開始:
{"type": "duration", "duration": 7200000}
2.1.3 常用時間段聚合粒度
時間聚合粒度的特例,方便使用,如年、月、日、小時等,日期標準是ISO 8601。無特別指定的情況下,year從1月份開始,month從1號開始,week從週一開始。
一般的格式為:其中timeZone可選,預設值是UTC;origin可選,預設1970-01-01T00:00:00;
{"type": "period", "period": "P2D", "timeZone": "America/Los_Angeles"}
period的一般寫法為:
month:P2M代表2個月作為一個聚合粒度;
week:P2W代表2周作為一個聚合粒度;
day:P1D代表1天作為一個聚合粒度;
hour:PT1H代表1個小時作為一個聚合粒度;
minute:PT0.750S代表750s作為一個聚合粒度;
如提交一個1d作為聚合粒度的groupby查詢的query:
{
"queryType":"groupBy",
"dataSource":"my_dataSource",
"granularity":{"type": "period", "period": "P1D", "timeZone": "America/Los_Angeles"},
"dimensions":[
"language"
],
"aggregations":[
{
"type":"count",
"name":"count"
}
],
"intervals":[
"1999-12-31T16:00:00.000-08:00/2999-12-31T16:00:00.000-08:00"
]
}
查詢得到的結果為:
[ {
"version" : "v1",
"timestamp" : "2013-08-30T00:00:00.000-07:00",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-08-31T00:00:00.000-07:00",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T00:00:00.000-07:00",
"event" : {
"count" : 2,
"language" : "en"
}
} ]
官網給出的例子是以美國洛杉磯的時區為準,一般中國的時區這樣使用,更多時區可移步該連結查詢:
"granularity": {
"period": "PT1H",
"timeZone": "+08:00",
"type": "period"
}
一個filter即一個json物件,代表一個過濾條件,等價於mysql中的一個where條件;過濾器的型別主要有:Selector filter,Regular expression filter(正則表示式過濾)、Logical expression filters(AND、OR、NOT)、In filter、Bound filter、Search filter、JavaScript filter、Extraction filter;
2.2.1 Selector 過濾器
等價於 WHERE <dimension_string> = '<dimension_value_string>'
json格式:
"filter": { "type": "selector", "dimension": <dimension_string>, "value": <dimension_value_string> }
2.2.2 正則表示式 過濾器
類似Selector過濾器,只不過過濾使用的是正則表示式;正則表示式為標準的java正則表示式規範;
"filter": { "type": "regex", "dimension": <dimension_string>, "pattern": <pattern_string> }
2.2.3 邏輯表示式 過濾器
AND
"filter": { "type": "and", "fields": [<filter>, <filter>, ...] }
OR
"filter": { "type": "not", "field": <filter> }
NOT
"filter": { "type": "not", "field": <filter> }
IN
等價於
SELECT COUNT(*) AS 'Count' FROM `table` WHERE `outlaw` IN ('Good', 'Bad', 'Ugly')
{
"type": "in",
"dimension": "outlaw",
"values": ["Good", "Bad", "Ugly"]
}
BOUND
數值型:21<=age<=31
{ "type": "bound", "dimension": "age", "lower": "21", "upper": "31" , "ordering": "numeric" }
數值型:21<age<31
{ "type": "bound", "dimension": "age", "lower": "21", "lowerStrict": true, "upper": "31" , "upperStrict": true, "ordering": "numeric" }
字元型:‘foo’<=name<='hoo'
{ "type": "bound", "dimension": "name", "lower": "foo", "upper": "hoo" }
aggregations即彙總資料記性druid之前提供的一個數據採集一種聚合方式。常用的聚合型別主要有:count,sum,min/max,approximate,miscellaneous;
2.3.1 Count aggregator
符合查詢條件的行數,類似mysql中的count計算:
{ "type" : "count", "name" : <output_name> }
Note: Druid進行Count查詢的資料量並不一定等於資料採集時匯入的資料量,因為Druid在採集資料查詢時已經按照相應的聚合方式對資料進行了聚合。
2.3.2 Sum aggregator
與底層druid表中的欄位型別一致。
longSum
{ "type" : "longSum", "name" : <output_name>, "fieldName" : <metric_name> }
doubleSum
{ "type" : "doubleSum", "name" : <output_name>, "fieldName" : <metric_name> }
2.3.3 MIN/MAX aggregator
doubleMin
{ "type" : "doubleMin", "name" : <output_name>, "fieldName" : <metric_name> }
doubleMax
{ "type" : "doubleMax", "name" : <output_name>, "fieldName" : <metric_name> }
long型別類似,不在贅述。其他聚合方式請移步到官網查詢示例。
2.4 聚合查詢
query
{
"queryType": "timeseries",
"dataSource": "sample_datasource",
"granularity": "day",
"descending": "true",
"filter": {
"type": "and",
"fields": [
{ "type": "selector", "dimension": "sample_dimension1", "value": "sample_value1" },
{ "type": "or",
"fields": [
{ "type": "selector", "dimension": "sample_dimension2", "value": "sample_value2" },
{ "type": "selector", "dimension": "sample_dimension3", "value": "sample_value3" }
]
}
]
},
"aggregations": [
{ "type": "longSum", "name": "sample_name1", "fieldName": "sample_fieldName1" },
{ "type": "doubleSum", "name": "sample_name2", "fieldName": "sample_fieldName2" }
],
"postAggregations": [
{ "type": "arithmetic",
"name": "sample_divide",
"fn": "/",
"fields": [
{ "type": "fieldAccess", "name": "postAgg__sample_name1", "fieldName": "sample_name1" },
{ "type": "fieldAccess", "name": "postAgg__sample_name2", "fieldName": "sample_name2" }
]
}
],
"intervals": [ "2012-01-01T00:00:00.000/2012-01-03T00:00:00.000" ]
}
query屬性說明
屬性 | 描述 | 是否必填 |
querytype | 字串型別,時間序列 "timeseries" | 是 |
dataSource | 字串型別,資料來源 | 是 |
descending | 排序方式,預設false | 否 |
intervals | 查詢時間範圍 | 是 |
granularity | 聚合粒度,說明 | 是 |
filter | 過濾條件,說明 | 否 |
aggregations | 聚合,說明 | 是 |
postAggregations | 後聚合,說明 | 否 |
context | 上下文,說明 |
否 |
上述query的返回結果:
[
{
"timestamp": "2012-01-01T00:00:00.000Z",
"result": { "sample_name1": <some_value>, "sample_name2": <some_value>, "sample_divide": <some_value> }
},
{
"timestamp": "2012-01-02T00:00:00.000Z",
"result": { "sample_name1": <some_value>, "sample_name2": <some_value>, "sample_divide": <some_value> }
}
]
TopN查詢根據規範返回給定維度的有序的結果集,從概念上來講,TopN查詢被認為單維度、有序的類似分組查詢。在某些情況下,TopN查詢比分組查詢(groupby query)快。TopN查詢結果返回Json陣列物件。TopN在每個節點將頂上K個結果排名,在Druid預設情況下最大值為1000。在實踐中,如果你要求前1000個項順序排名,那麼從第1-999個項的順序正確性是100%,其後項的結果順序沒有保證。你可以通過增加threshold值來保證順序準確。
query
{
"queryType": "topN",
"dataSource": "sample_data",
"dimension": "sample_dim",
"threshold": 5,
"metric": "count",
"granularity": "all",
"filter": {
"type": "and",
"fields": [
{
"type": "selector",
"dimension": "dim1",
"value": "some_value"
},
{
"type": "selector",
"dimension": "dim2",
"value": "some_other_val"
}
]
},
"aggregations": [
{
"type": "longSum",
"name": "count",
"fieldName": "count"
},
{
"type": "doubleSum",
"name": "some_metric",
"fieldName": "some_metric"
}
],
"postAggregations": [
{
"type": "arithmetic",
"name": "sample_divide",
"fn": "/",
"fields": [
{
"type": "fieldAccess",
"name": "some_metric",
"fieldName": "some_metric"
},
{
"type": "fieldAccess",
"name": "count",
"fieldName": "count"
}
]
}
],
"intervals": [
"2013-08-31T00:00:00.000/2013-09-03T00:00:00.000"
]
}
query屬性說明
屬性 | 描述 | 是否必填 |
querytype | 字串型別,時間序列 "topN" | 是 |
dataSource | 字串型別,資料來源,說明 | 是 |
dimension | groupBy的維度,說明 | 是 |
intervals | 查詢時間範圍 | 是 |
granularity | 聚合粒度,說明 | 是 |
filter | 過濾條件,說明 | 否 |
aggregations | 聚合,說明 | 是 |
postAggregations | 後聚合,說明 | 否 |
threshold | topN的N值 | 是 |
metric | 字串或Json物件指定度量對Top N個結果排序,說明 | 否 |
context | 上下文,說明 | 否 |
上述query的查詢結果形如:
[
{
"timestamp": "2013-08-31T00:00:00.000Z",
"result": [
{
"dim1": "dim1_val",
"count": 111,
"some_metrics": 10669,
"average": 96.11711711711712
},
{
"dim1": "another_dim1_val",
"count": 88,
"some_metrics": 28344,
"average": 322.09090909090907
},
{
"dim1": "dim1_val3",
"count": 70,
"some_metrics": 871,
"average": 12.442857142857143
},
{
"dim1": "dim1_val4",
"count": 62,
"some_metrics": 815,
"average": 13.14516129032258
},
{
"dim1": "dim1_val5",
"count": 60,
"some_metrics": 2787,
"average": 46.45
}
]
}
]
類似mysql中的groupBy查詢方式。
query
{
"queryType": "topN",
"dataSource": "sample_data",
"dimension": "sample_dim",
"threshold": 5,
"metric": "count",
"granularity": "all",
"filter": {
"type": "and",
"fields": [
{
"type": "selector",
"dimension": "dim1",
"value": "some_value"
},
{
"type": "selector",
"dimension": "dim2",
"value": "some_other_val"
}
]
},
"aggregations": [
{
"type": "longSum",
"name": "count",
"fieldName": "count"
},
{
"type": "doubleSum",
"name": "some_metric",
"fieldName": "some_metric"
}
],
"postAggregations": [
{
"type": "arithmetic",
"name": "sample_divide",
"fn": "/",
"fields": [
{
"type": "fieldAccess",
"name": "some_metric",
"fieldName": "some_metric"
},
{
"type": "fieldAccess",
"name": "count",
"fieldName": "count"
}
]
}
],
"intervals": [
"2013-08-31T00:00:00.000/2013-09-03T00:00:00.000"
]
}
query屬性說明
屬性 | 描述 | 是否必填 |
querytype | 字串型別,時間序列 "topN" | 是 |
dataSource | 字串型別,資料來源,說明 | 是 |
dimensions | groupBy的維度,說明 | 是 |
intervals | 查詢時間範圍 | 是 |
granularity | 聚合粒度,說明 | 是 |
filter | 過濾條件,說明 | 否 |
aggregations | 聚合,說明 | 是 |
postAggregations | 後聚合,說明 | 否 |
limitSpec | 返回指定數量的查詢結果,類似mysql中的limit字句,說明 | 否 |
having | 類似mysql中的having字句,說明 | 否 |
context | 上下文,說明 | 否 |
上述query的查詢結果形如:
[
{
"timestamp": "2013-08-31T00:00:00.000Z",
"result": [
{
"dim1": "dim1_val",
"count": 111,
"some_metrics": 10669,
"average": 96.11711711711712
},
{
"dim1": "another_dim1_val",
"count": 88,
"some_metrics": 28344,
"average": 322.09090909090907
},
{
"dim1": "dim1_val3",
"count": 70,
"some_metrics": 871,
"average": 12.442857142857143
},
{
"dim1": "dim1_val4",
"count": 62,
"some_metrics": 815,
"average": 13.14516129032258
},
{
"dim1": "dim1_val5",
"count": 60,
"some_metrics": 2787,
"average": 46.45
}
]
}
]
groupBy多值欄位
Druid中的欄位會有多值查詢,針對多值查詢的groupBy操作,滿足多值中一個過濾條件,查詢結果中會把多值欄位中的每個值都返回。下面通過例子進行說明。
底層資料格式
{"timestamp": "2011-01-12T00:00:00.000Z", "tags": ["t1","t2","t3"]} #row1
{"timestamp": "2011-01-13T00:00:00.000Z", "tags": ["t3","t4","t5"]} #row2
{"timestamp": "2011-01-14T00:00:00.000Z", "tags": ["t5","t6","t7"]} #row3
{"timestamp": "2011-01-14T00:00:00.000Z", "tags": []} #row4
查詢query:
{
"queryType": "groupBy",
"dataSource": "test",
"intervals": [
"1970-01-01T00:00:00.000Z/3000-01-01T00:00:00.000Z"
],
"filter": {
"type": "selector",
"dimension": "tags",
"value": "t3"
},
"granularity": {
"type": "all"
},
"dimensions": [
{
"type": "default",
"dimension": "tags",
"outputName": "tags"
}
],
"aggregations": [
{
"type": "count",
"name": "count"
}
]
}
返回結果:命中row1和row2
[
{
"timestamp": "1970-01-01T00:00:00.000Z",
"event": {
"count": 1,
"tags": "t1"
}
},
{
"timestamp": "1970-01-01T00:00:00.000Z",
"event": {
"count": 1,
"tags": "t2"
}
},
{
"timestamp": "1970-01-01T00:00:00.000Z",
"event": {
"count": 2,
"tags": "t3"
}
},
{
"timestamp": "1970-01-01T00:00:00.000Z",
"event": {
"count": 1,
"tags": "t4"
}
},
{
"timestamp": "1970-01-01T00:00:00.000Z",
"event": {
"count": 1,
"tags": "t5"
}
}
]
遇到的問題及解決方法
問題1:北京時區進行查詢
解決方法:通過設定timeZone的時區解決
"granularity": {
"period": "PT1H",
"timeZone": "+08:00",
"type": "period"
}
問題2:獲取datasource的最新build時間
解決方法:在context中設定requireMessageWatermark=true,在http返回結果的header中拿到該資料;
if (HttpStatus.SC_OK == httpResponse.getStatusLine().getStatusCode()) {
HttpEntity entity = httpResponse.getEntity();
result.setResultStr(EntityUtils.toString(entity, "utf-8"));
String waterMark = httpResponse.getHeaders(DRUID_WATERMARK_HEADER)[0].getValue();
if (StringUtil.isNotEmpty(waterMark)) {
JSONObject obj = JSONObject.parseObject(waterMark);
waterMark = obj.getString(DRUID_MESSAGE_WATERMARK);
result.setDruidWatermarkStr(waterMark);
} // end if
}
問題3:設定不同query的優先順序
解決方法:在context中設定priority屬性;
問題4:設定query的超時時間
解決方法:在context中設定timeout屬性;
問題5:多值groupBy指定返回想要的值
解決方法:使用listField屬性設定多值列中想要的值;
{
"queryType": "groupBy",
"dataSource": "test",
"intervals": [
"1970-01-01T00:00:00.000Z/3000-01-01T00:00:00.000Z"
],
"filter": {
"type": "selector",
"dimension": "tags",
"value": "t3"
},
"granularity": {
"type": "all"
},
"dimensions": [
{
"type": "listFiltered",
"delegate": {
"type": "default",
"dimension": "tags",
"outputName": "tags"
},
"values": ["t3"]
}
],
"aggregations": [
{
"type": "count",
"name": "count"
}
]
}
附Druid官網連結
相關推薦
Druid學習之查詢語法
寫在前面 最近一段時間都在做druid實時資料查詢的工作,本文簡單將官網上的英文文件加上自己的理解翻譯成中文,同時將自己遇到的問題及解決方法list下,防止遺忘。 本文的demo示例均來源於官網。 Druid查詢概述 Druid的查詢是使用Rest風格的http請求查詢服務節點,客戶端通過傳送Json物件請
python學習之基礎語法循環語句
21.輸入一個5位數字,判斷其位數: val = input("please input a 1-99999 number:") vals = int(val) if vals >= 1000: if vals >=10000: print("This is 5")
(4)Smali系列學習之Smali語法詳解內部類
這一 數字 學習 get 私有方法 如果 單獨 hello 我們 在這一節,我們來介紹一下內部類。對於Java文件中的每一個內部類,都會產生一個單獨的smali文件,比如ActivityThread$1.smali。這些文件的命名規範是如果是匿名內部類,則命名規則是外部類+
Druid學習之路 (五)Druid的資料攝取任務型別
作者:Syn良子 出處:https://www.cnblogs.com/cssdongl/p/9885534.html 轉載請註明出處 Druid的資料攝取任務型別 Druid支援很多種型別的資料攝取任務.任務通過CURL POST的方式提交到Overlord節點然後分配給middle manager
【Spring】Sping Data JPA 深入學習之①查詢方法原理探究
基本概念 Spring Data JPA是Spring公司開發的Java Persistence API 相對於 sun公司開發的JPA Spring Data JPA 整合了Hibernate,換句話說,Spring Data JPA 的預設實現是用的Hibernate
Hive學習之基礎語法
1、建立資料庫 create database 資料庫名; 2、使用資料庫 use 資料庫名; 3、建立表 內部表:表目錄安裝hive的規範來部署,位於hive倉庫目錄/user/hive/warehouse中 create table t_pv_log(ip string,
Lua的自我學習之路-語法學習1
要點1: Lua句末的分號可不寫,但我習慣性寫上 print("hello World"); print("hello World") 要點2:註釋 單行註釋:主要是前面2個 "-" --printfddsa 單
prometheus 之 查詢語法(操作符)
操作符 二元操作符 Prometheus的查詢語言支援基本的邏輯運算和算術運算。對於兩個瞬時向量, 匹配行為可以被改變。 算術二元運算子 在Prometheus系統中支援下面的二元算術操作符: + 加法 - 減法 * 乘法 / 除法 % 模
prometheus 之 查詢語法(函式列表)
函式列表 一些函式有預設的引數,例如:year(v=vector(time()) instant-vector)。v是引數值,instant-vector是引數型別。vector(time())是預設值。 abs() abs(v instant-vector)返回輸入向量的所有樣
Dart學習之基礎語法
承接上一篇我們搭建了Dart環境,這一篇我們將學習Dart的基礎語法。 Dart的所有東西都是物件,包括數字,函式等。它們都繼承自Object,預設是都是null(包括數字),所以數字,字串
python3學習之基礎語法
參考教程基礎語法 1.編碼 預設情況下,Python 3 原始碼檔案以 UTF-8 編碼,所有字串都是 unicode 字串。 當然你也可以為原始碼檔案指定不同的編碼: # -*-coding: utf-8 -*- 需要指出的是,’#’,’:’,與編碼值
mybatis學習之查詢快取
編寫mapper.xml,配置tyoe為ehcache對cache介面的實現型別 <!-- 開啟本mapper的namespace下的二級快取 type:指定cache介面的實現類的型別,預設使用PerpetualCache,要和EhCache整合,需要配置type為ehcac
Ruby學習之基礎語法知識
#!/usr/bin/ruby -w puts "Hello, Ruby!"; 之前我們已經通過一個簡單的指令碼輸出過一些內容,接下來我們就來看下Ruby 語法相關的基本概念。 首先是Ruby程式碼中的空白字元,像空格和製表符,就一般會被忽略,除非它們出現在字串中才會改觀,不過有時候他們
React Native學習之JavaScript語法轉換器
JavaScript語法轉換器 語法轉換器可以使編寫程式碼的過程更加享受,因為開發者可以藉助轉換器直接使用新的JavaScirpt語法標準,而無需等待JS直譯器的支援。 React Native從0.5.0版本開始已經內建Babel轉換器。你可以檢視Babe
SAS學習之查詢異常值
1.查詢缺失值的萬能程式 data missing; set sasuser.xb; array cha[*] _character_ \*利用*好不指定cha陣列中的字元型變數個數*\ do i=1 to dim(cha); \*指定迴圈次數為陣列cha中的
R語言學習之基本語法
ggplot2圖形之基本語法: ggplot2的核心理念是將繪圖與資料分離,資料相關的繪圖與資料無關的繪圖分離 ggplot2是按圖層作圖 ggplot2保有命令式作圖的調整函式,使其更具靈活性 ggplot2將常見的統計變換融入到了繪圖中。 ggplot的繪圖有以下幾個特
mybatis學習之查詢結果返回List以及Map
當要查詢的結果不是單個記錄而是一個集合的時候,mybatis的resultType寫的依然是集合中的物件的型別名稱,例如: <select id="getPersonByNameLike"resultType="mybatis_01.Pers
學習筆記SQL提交查詢語法之WHERE子句的應用和規則[圖]
居住 總結 數據庫比較 需要 希望 復習 href 如果 引號 俗話說,活到老,學到老,我就是半路出來學習編程的年輕人了,因為個人對於程序有興趣,因此從一開始就自學,但是難度也非常大,目前在學習數據庫了,對於一些語法和技巧,寫一些學習心得筆記,記錄下來,以後也方便復習。最近
Elasticsearch學習之多種查詢方式
完全 mar commerce 生產 pro 命令行 str 令行 {} 1. query string search 搜索全部商品:GET /ecommerce/product/_search took:耗費了幾毫秒 timed_out:是否超時,這裏是沒有
Elasticsearch學習之深入搜索一 --- 提高查詢的精準度
ast 多少 opera 相關度 滿足 ini 無法 sea 進行 1. 為帖子增加標題字段 POST /forum/article/_bulk { "update": { "_id": "1"} } { "doc" : {"title" : "this is java