Using Bind() function in gocql

297 views
Skip to first unread message

Vivek Bhat

unread,
Aug 6, 2020, 3:52:14 AM8/6/20
to gocql

Hi all,

Currently our service uses gocql to fetch the data from Apache Cassandra.  In Cassandra the usage of query with `where in` is not recommended due to performance issues. So I was trying to implement the execution of the select query parallel to Cassandra using go routines.


Example: 

A request for 5 gtin13s would create 5 different goroutines of `p.getAll` and would then run generate the result.


My question:

Currently I’m creating multiple instances of `gocql.Query` in the call for function `getAlll` because if I try to use the same instance of `gocql.Query` the bind would not work and result in duplicate values. 

Is there an alternative approach of doing this?  Please help me on this.


```

type dbRespWithErrors struct {

Gtin13  string

Product Product

Err     error

}



type Product{

Gtin13  string

Name string

}



func (p product) GetProducts(session *gocql.Session, gtin13s []string) ([]Product, error) {

var productCounter = 0


respFromDB := make(chan dbRespWithErrors, len(gtin13s))


query := " Select " + columns + " from " + dto.Products


if len(gtin13s) > 0 {

query = query + " where Gtin13 = ?"

}


preparedQuery := session.Query(query)


for _, gtin13 := range gtin13s {

//Creating multiple instance of prepared query when we call the getAll function

go p.getAll(*preparedQuery, gtin13, respFromDB)

}


var prods []dto.Product

for p := range respFromDB {

productCounter++


if p.Product != nil {

prods = append(prods, *p.Product)

}


if productCounter == len(gtin13s) {

close(respFromDB)

}

}


return prods, nil

}


func (p product) getAll(preparedStatement gocql.Query, gtin13 string, product chan dbRespWithErrors) {


var (

err      error

prodResp dbRespWithErrors

)


prod := Product{}

prodResp = dbRespWithErrors{

Gtin13: gtin13,

}


err = preparedStatement.Bind(gtin13).Scan(&prod.gtin13,&prod.Name)

if err != nil {

prodResp.Err = err

product <- prodResp


return

}


prodResp.Product = &prod

product <- prodResp


}

```



Also we had migrated the data from Apache Cassandra to cosmos db Cassandra API. 

And when we tried running the same code above the output was quite unexpected.


For example:

A function call like 

`p.GetProducts(session,[]string{“12345”,”12346”,“12347”,”12348”,“12349”})`


Would result in the response 

```

[]Product{

{

Gtin13:12345

Name:x

},

{

Gtin13:12346

Name:y

},

{

Gtin13:12345

Name:x

},

{

Gtin13:12348

Name:z

},

{

Gtin13:12346

Name:y

}

}

```


I.e some of the rows are repeated and others are ignored. How can I debug this specific issue? Any help would be appreciated.

Thanks and regards,

Vivek Bhat

night...@googlemail.com

unread,
Aug 6, 2020, 12:43:10 PM8/6/20
to gocql
Using bind is not necessary in gocql.
col2_value := 1
session.Query("SELECT col1 FROM my table WHERE col2=?;", col2_value)

is all that you need for safe, easy and peformant query execution. gocql automatically prepares the statements for you and caches prepared statements.

Reply all
Reply to author
Forward
0 new messages