dso0139 2019-02-28 15:34
浏览 128

使用Cassandra GOCQL驱动程序(Golang)找出页面状态

I've been trying to wrap my head around how paging in Apache Cassandra with the driver functions in GOlang.

I have the following code for fetching rows

/// Assume all other prerequisites.

session, _ := cluster.CreateSession()

session.SetPageSize(100)
var pagestate []byte

query := session.Query(`select * from keyspace.my_table`)

query = query.PageState(pagestate)
if err := query.Exec(); != nil {
   panic(err)
}

iter := query.Iter()

for {
   row := map[string]interface{}{}
   if !iter.MapScan(row) {
      pagestate = iter.PageState()
      break
   }

   /// Do whatever I need with row.

}

What I'm trying to achieve: The table I'm referencing is huge, over 18k rows huge, and I want to fetch all of them for a special operation in the most efficient manner using the driver's built in paging so the query won't time out.

The problem: I'm not sure how to get the query to resume at the previous page state. I'm not sure if this involves running the query in a loop and managing page state outside of it or not. I understand how to get and set page state, I can't figure out how to iterate the query with a new page sate each time without a proper halt condition when all the paging is done.

My best attempt:

var pagestate []byte

query := session.Query(`select * from keyspace.my_table`)

for {
   query = query.PageState(pagestate)
   if err := query.Exec(); != nil {
      panic(err)
   }

   iter := query.Iter()

   /// I don't know if I'm using this bool correct or not.
   /// My assumption is that this would return false when a new page isn't
   /// avaliable, thus meaning that all the pages have been filled and
   /// the loop can exit.
   if !iter.WillSwitchPage() {
      break
   }

   for {
      row := map[string]interface{}{}
      if !iter.MapScan(row) {
         pagestate = iter.PageState()
         break
      }

      /// Do whatever I need with row.
   }
}

Am I doing this right, or is there a better way to achieve this?

  • 写回答

1条回答 默认 最新

  • douji1058 2019-02-28 16:21
    关注

    So, as it turns out, WillSwitchPage() will never return true at any point in the loop. Not sure why. I guess it's because of how I'm using MapScan() to control the inner loop.

    Anyway, I figured out a solution by checking the []byte for the page state itself at the en dof the query loop. If the driver reaches the end and doesn't fill the page, page state will have 0 elements, so I'm using that as my halt condition. This may or may not be the most elegant or intended way to handle the driver's pagination, but it's functioning as wanted.

    var pagestate []byte
    
    query := session.Query(`select * from keyspace.my_table`)
    
    for {
       query = query.PageState(pagestate)
       if err := query.Exec(); != nil {
          panic(err)
       }
    
       iter := query.Iter()
    
       for {
          row := map[string]interface{}{}
          if !iter.MapScan(row) {
             pagestate = iter.PageState()
             break
          }
    
          /// Do whatever I need with row.
       }
    
       if len(pagestate) == 0 {
          break
       }
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line