[英]Google Big table Filter with Java
我想過濾與此條件匹配的所有行:使用輸入值x
,返回 Java 中兩個量詞值之間的所有記錄。
示例:輸入值x = 15
,
量詞q1 = 10
和q2 = 20
的記錄將匹配,量詞q1 = 1
和q2 = 10
的記錄將不匹配
可以對一系列值創建過濾器,但這取決於您對它們進行編碼的方式。 如果它們被編碼為字符串,您將使用 ValueRange 過濾器,如下所示:
Filter filter = FILTERS.value().range().startClosed("10").endClosed("20");
然后使用過濾器執行讀取
try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) {
Query query = Query.create(tableId).filter(filter);
ServerStream<Row> rows = dataClient.readRows(query);
for (Row row : rows) {
printRow(row);
}
} catch (IOException e) {
System.out.println(
"Unable to initialize service client, as a network error occurred: \n" + e.toString());
}
您還可以將字節傳遞給范圍,因此如果您的數字以某種方式編碼,您可以以相同的方式將它們編碼為字節並將其傳遞給startClosed
和endClosed
。
您可以在 Cloud Bigtable 文檔中閱讀有關過濾器的更多信息。
您正在嘗試過濾包含小於 x 的最小數值限定符以及包含大於 x 的最大數值限定符的行,然后您可能正在嘗試過濾這些限定符之間的那些行中的數據。
這與設置 BigTable 時嘗試實現的訪問模式完全相反。 這有一種代碼味道。 話雖如此,您可以使用過濾器的組合成功地實現這種查詢。 但是,據我所知,這些過濾器不能鏈接在一起。
首先,使用過濾器獲取 cq < x 的鍵。 接下來,根據第一個過濾器的每個鍵向 bigtable 發送一個查詢,並過濾鍵以及過濾器,使得 cq > x。 這是一種優化的方式。 一種更優化的方法可能是將第一個過濾器限制為 1 個元素(即獲取 min 元素),並且在第二步之后僅對 lessThen 部分進行無限制的查詢。
我在下面的實現稍微簡單一些,因為第二步只過濾 cq > x,而不是第一步的鍵。 但要點是一樣的:
val x = "15"
val a = new mutable.HashMap[ByteString, Row]
val b = new mutable.HashMap[ByteString, Row]
val c = new mutable.HashMap[ByteString, Row]
dataClient.readRows( Query.create(tableId)
.filter(Filters.FILTERS.qualifier().rangeWithinFamily("cf").startClosed(Int.MinValue.toString.padTo(Ints.max(Int.MinValue.toString.length, Int.MaxValue.toString.length), "0").toString()).endOpen(x.padTo(Ints.max(Int.MinValue.toString.length, Int.MaxValue.toString.length), "0").toString()
)))
.forEach(r => a.put(r.getKey, r))
dataClient.readRows(Query.create(tableId)
.filter(Filters.FILTERS.qualifier().rangeWithinFamily("cf").startOpen(x).endClosed(Int.MaxValue.toString.padTo(Ints.max(Int.MinValue.toString.length, Int.MaxValue.toString.length), "0").toString()))
)
.forEach(r => b.put(r.getKey, r))
dataClient.readRows(Query.create(tableId)
.filter(Filters.FILTERS.qualifier().exactMatch(x)))
.forEach(r => c.put(r.getKey, r))
val all_cells = a.keys.toSet.intersect(b.keys.toSet).flatMap(k => a.get(k).map(_.getCells).get.toArray.toSeq ++ b.get(k).map(_.getCells).get.toArray.toSeq
++ c.get(k).map(_.getCells).get.toArray.toSeq)
你能告訴我更多關於你的用例嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.