简体   繁体   中英

Using nodejs 'cassandra-driver' prepared query with IN query

This is a potential newbie question but I couldn't find an answer out in the wild.

I'm currently building a simple user event log of this form (some attributes elided to keep this simple):

CREATE TABLE events.by_hour (
  level tinyint, /* 60 = FATAL, 10 = TRACE */
  hour int, /*  in YYYYMMDDHH format */
  insertion_time timeuuid,
  userid TEXT,
  message TEXT,
PRIMARY KEY ((type,hour),userid,insertion_time))
WITH CLUSTERING ORDER BY (userid ASC, insertion_time ASC);

I would like to make a prepared query to fetch all events optionally filtered by a given user over some set of levels ideally over the course of several hours.

I can easily build a query that queries a single level and hour:

var cassandra = require('cassandra-driver');
var client = new cassandra.Client({contactPoints: ['127.0.0.1']});

var query 
    = 'SELECT * FROM events.by_hour 
      WHERE level IN (?) and hour IN (?) and userid = ?;';

var options = [ 10, 2016032117,'user_uuid' ];

client.execute(query, options, {
                    prepare: true
                }, function (err, result) {
                    // Do stuff... 
                    next(err);
                });

This works fine for a single hour and level. I would love to specify multiple hours and levels in the above query but playing with the code I'm unable to get that to work either by specifying the set as a string or as an array of values.

I think I'm forced to do something like this:

Build the query based upon the number of levels and hours are needed:

// for 1 level and 2 hours:
query = 'SELECT * FROM events.by_hour 
      WHERE level IN (?) and hour IN (?,?) and userid = ?;';

options = [ 10, 2016032117,2016032118,'user_uuid' ];

client.execute(query, options, {
                    prepare: true
                }, function (err, result) {
                    // Do stuff... 
                    next(err);
                });

// for 2 levels and 2 hours:
query = 'SELECT * FROM events.by_hour 
      WHERE level IN (?,?) and hour IN (?,?) and userid = ?;';

options = [ 10, 20, 2016032117,2016032118,'user_uuid' ];

client.execute(query, options, {
                    prepare: true
                }, function (err, result) {
                    // Do stuff... 
                    next(err);
                });

I don't love this. BUT I can still get the benefits of prepared queries even here since we can just pass in 'prepared: true'. It feels like there should be a better way... but I'm not sure what I'm trying to do is even possible with single prepared query.

Can anyone lend some wisdom here?

Thanks!

You should use the IN operator followed by the query marker (no parenthesis) and provide the parameter for the query marker as an array:

const query = 'SELECT * FROM events.by_hour WHERE level IN ? and ' + 
              'hour IN ? and userid = ?';
const params = [ [ 10, 20, 30] , [ 2016032117, 2016032118 ],'user_uuid' ];
client.execute(query, params, { prepare: true }, callback);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM