Table Store支援在查詢資料時使用過濾器在服務端按指定條件進行資料過濾,本文介紹如何在 Go SDK 中使用過濾器。
前提條件
過濾器類型
Table Store的過濾器類型包括以下 3 種。
單屬性列值過濾器(SingleColumnCondition):判斷單個屬性列的值是否符合條件。
單屬性列正則過濾器(SingleColumnValueRegexFilter):將 String 類型的屬性列按照指定的Regex匹配子字串後轉換成指定的資料類型,再判斷是否符合條件。
組合過濾器(CompositeColumnCondition):將多個條件組合進行資料過濾。
單屬性列值過濾器
func NewSingleColumnCondition(columnName string, comparator ComparatorType, value interface{}) *SingleColumnCondition範例程式碼
以下範例程式碼以範圍查詢為例查詢主索引值為 [row1, row3) 的行資料,並在查詢後進行過濾,返回 col1 屬性列的值等於 val1 的行資料。
func SingleValueFilterSample(client *tablestore.TableStoreClient) {
// 構建查詢條件
rangeRowQueryCriteria := &tablestore.RangeRowQueryCriteria{}
rangeRowQueryCriteria.TableName = "test_table"
// 設定查詢起始主鍵
startPK := new(tablestore.PrimaryKey)
startPK.AddPrimaryKeyColumn("id", "row1")
rangeRowQueryCriteria.StartPrimaryKey = startPK
// 設定查詢結束主鍵(返回結果不包含結束主鍵)
endPK := new(tablestore.PrimaryKey)
endPK.AddPrimaryKeyColumn("id", "row3")
rangeRowQueryCriteria.EndPrimaryKey = endPK
// 設定查詢版本
rangeRowQueryCriteria.MaxVersion = 1
// 構造過濾器,條件為 col1 == "val1"
singleColumnCondition := tablestore.NewSingleColumnCondition("col1", tablestore.CT_EQUAL, "val1")
rangeRowQueryCriteria.Filter = singleColumnCondition
// 調用 GetRange 方法查詢資料
getRangeRequest := new(tablestore.GetRangeRequest)
getRangeRequest.RangeRowQueryCriteria = rangeRowQueryCriteria
getRangeResponse, err := client.GetRange(getRangeRequest)
// 返回結果處理
if err != nil {
fmt.Println("Range get failed with error: ", err)
} else {
fmt.Printf("* RequestId: %s \n", getRangeResponse.RequestId)
fmt.Printf("* Read CU Cost: %d \n", getRangeResponse.ConsumedCapacityUnit.Read)
fmt.Printf("* Write CU Cost: %d \n", getRangeResponse.ConsumedCapacityUnit.Write)
fmt.Println("* Rows Data:")
for _, row := range getRangeResponse.Rows {
fmt.Printf("PrimaryKey: %v; Columns: ", row.PrimaryKey.PrimaryKeys)
for _, column := range row.Columns {
fmt.Printf("%v ", column)
}
fmt.Printf("\n")
}
}
}設定行資料不包含判斷的屬性列時,不返回該行。
singleColumnCondition.FilterIfMissing = true設定只判斷查詢結果中屬性列最新的資料版本。
singleColumnCondition.LatestVersionOnly = true
單屬性列正則過濾器
只有 String 類型的屬性列支援使用正則過濾器。
func NewSingleColumnValueRegexFilter(columnName string, comparator ComparatorType, rule *ValueTransferRule, value interface{}) *SingleColumnCondition範例程式碼
以下範例程式碼以範圍查詢為例查詢主索引值為 [row1, row3) 的行資料,並在查詢後進行正則匹配過濾,返回 col1 屬性列的值滿足Regex 1([a-z]+)5 且匹配到的子字串為 aaa 的行資料。
func SingleRegexFilterSample(client *tablestore.TableStoreClient) {
// 構建查詢條件
rangeRowQueryCriteria := &tablestore.RangeRowQueryCriteria{}
rangeRowQueryCriteria.TableName = "test_table"
// 設定查詢起始主鍵
startPK := new(tablestore.PrimaryKey)
startPK.AddPrimaryKeyColumn("id", "row1")
rangeRowQueryCriteria.StartPrimaryKey = startPK
// 設定查詢結束主鍵(返回結果不包含結束主鍵)
endPK := new(tablestore.PrimaryKey)
endPK.AddPrimaryKeyColumn("id", "row3")
rangeRowQueryCriteria.EndPrimaryKey = endPK
// 設定查詢版本
rangeRowQueryCriteria.MaxVersion = 1
// 構造過濾器,條件為 cast<String>(reg(col1)) == “aaa”
valueTransferRule := tablestore.NewValueTransferRule("1([a-z]+)5", tablestore.Variant_STRING)
singleColumnValueRegexFilter := tablestore.NewSingleColumnValueRegexFilter("col1", tablestore.CT_EQUAL, valueTransferRule, "aaa")
rangeRowQueryCriteria.Filter = singleColumnValueRegexFilter
// 調用 GetRange 方法查詢資料
getRangeRequest := new(tablestore.GetRangeRequest)
getRangeRequest.RangeRowQueryCriteria = rangeRowQueryCriteria
getRangeResponse, err := client.GetRange(getRangeRequest)
// 返回結果處理
if err != nil {
fmt.Println("Range get failed with error: ", err)
} else {
fmt.Printf("* RequestId: %s \n", getRangeResponse.RequestId)
fmt.Printf("* Read CU Cost: %d \n", getRangeResponse.ConsumedCapacityUnit.Read)
fmt.Printf("* Write CU Cost: %d \n", getRangeResponse.ConsumedCapacityUnit.Write)
fmt.Println("* Rows Data:")
for _, row := range getRangeResponse.Rows {
fmt.Printf("PrimaryKey: %v; Columns: ", row.PrimaryKey.PrimaryKeys)
for _, column := range row.Columns {
fmt.Printf("%v ", column)
}
fmt.Printf("\n")
}
}
}組合過濾器
最多支援 32 個條件的組合。
func NewCompositeColumnCondition(lo LogicalOperator) *CompositeColumnValueFilter範例程式碼
以下範例程式碼以範圍查詢為例查詢主索引值為 [row1, row3) 的行資料,並使用組合過濾器進行資料過濾。
func CompositeFilterSample(client *tablestore.TableStoreClient) {
// 構建查詢條件
rangeRowQueryCriteria := &tablestore.RangeRowQueryCriteria{}
rangeRowQueryCriteria.TableName = "test_table"
// 設定查詢起始主鍵
startPK := new(tablestore.PrimaryKey)
startPK.AddPrimaryKeyColumn("id", "row1")
rangeRowQueryCriteria.StartPrimaryKey = startPK
// 設定查詢結束主鍵(返回結果不包含結束主鍵)
endPK := new(tablestore.PrimaryKey)
endPK.AddPrimaryKeyColumn("id", "row3")
rangeRowQueryCriteria.EndPrimaryKey = endPK
// 設定查詢版本
rangeRowQueryCriteria.MaxVersion = 1
// 構造單屬性列值過濾器1,條件為 col1 == "val1"
singleColumnCondition1 := tablestore.NewSingleColumnCondition("col1", tablestore.CT_EQUAL, "val1")
// 構造單屬性列正則過濾器2,條件為 cast<String>(reg(col2)) == "aaa"
valueTransferRule := tablestore.NewValueTransferRule("1([a-z]+)5", tablestore.Variant_STRING)
singleColumnValueRegexFilter2 := tablestore.NewSingleColumnValueRegexFilter("col2", tablestore.CT_EQUAL, valueTransferRule, "aaa")
// 構造組合過濾器1,條件為 col1 == "val1" or cast<String>(reg(col2)) == "aaa"
compositeCondition1 := tablestore.NewCompositeColumnCondition(tablestore.LO_OR)
compositeCondition1.AddFilter(singleColumnCondition1)
compositeCondition1.AddFilter(singleColumnValueRegexFilter2)
// 構造單屬性列值過濾器2,條件為 col3 == "val3"
singleColumnCondition3 := tablestore.NewSingleColumnCondition("col3", tablestore.CT_EQUAL, "val3")
// 構造組合過濾器2,條件為 組合過濾器1 and 單屬性列值過濾器2,即 (col1 == "val1" or cast<String>(reg(col2)) == "aaa") and col3 == "val3"
compositeCondition2 := tablestore.NewCompositeColumnCondition(tablestore.LO_AND)
compositeCondition2.AddFilter(compositeCondition1)
compositeCondition2.AddFilter(singleColumnCondition3)
// 查詢結果添加過濾器
rangeRowQueryCriteria.Filter = compositeCondition2
// 調用 GetRange 方法查詢資料
getRangeRequest := new(tablestore.GetRangeRequest)
getRangeRequest.RangeRowQueryCriteria = rangeRowQueryCriteria
getRangeResponse, err := client.GetRange(getRangeRequest)
// 返回結果處理
if err != nil {
fmt.Println("Range get failed with error: ", err)
} else {
fmt.Printf("* RequestId: %s \n", getRangeResponse.RequestId)
fmt.Printf("* Read CU Cost: %d \n", getRangeResponse.ConsumedCapacityUnit.Read)
fmt.Printf("* Write CU Cost: %d \n", getRangeResponse.ConsumedCapacityUnit.Write)
fmt.Println("* Rows Data:")
for _, row := range getRangeResponse.Rows {
fmt.Printf("PrimaryKey: %v; Columns: ", row.PrimaryKey.PrimaryKeys)
for _, column := range row.Columns {
fmt.Printf("%v ", column)
}
fmt.Printf("\n")
}
}
}