I heard and learned that a query cannot be made with a partial partition key, all columns from the partition key must be provided otherwise it fails. But, in this case, it is not, the query does not fail and the return is right. However I've to admit that the case is particular because, it is a JUnit (in memory database) test.... Please, let me know where I'm wrong or if it is a bug or a new feature ? ;)
So, here are the version of the component I'm using.
<dependency> <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-extras</artifactId> <cassandra-driver-extras.version>3.10.2</cassandra-driver-extras.version> </dependency> <dependency> <groupId>com.datastax.cassandra</groupId> <artifactId>cassandra-driver-core</artifactId> <cassandra-driver.version>3.10.2</cassandra-driver.version> </dependency> <dependency> <groupId>org.cassandraunit</groupId> <artifactId>cassandra-unit-spring</artifactId> <cassandra-unit.version>3.11.2.0</cassandra-unit.version> </dependency>
Here is the model:
CREATE TABLE IF NOT EXISTS test ( company_id text, location_id text, user_id text, date_time timestamp, type text, id uuid, ... type text, external_id text, PRIMARY KEY ((company_id, location_id), user_id, date_time, type, id) ) WITH comment = 'Test for secondary index and partition key';
Here are the data
INSERT INTO test (company_id, location_id, user_id, date_time, type, id, status, external_id) VALUES ('5-company_id', '1-location_id', '1-user_id', 951822000000, 'TRAINING_START', 43026b3e-5746-4e78-a9c3-7635ad032bb0, 'QUEUED', 'The-External-Id') IF NOT EXISTS; INSERT INTO test (company_id, location_id, user_id, date_time, type, id, status, external_id) VALUES ('5-company_id', '2-location_id', '1-user_id', 951908400000, 'SHIFT_START', ba001e98-07a6-44ed-b191-810c10faf059, 'IMPORTED', 'The-External-Id') IF NOT EXISTS;
Query is:
final Select select = QueryBuilder.select().from("test") .where(eq(PKEY_COMPANY_ID, companyId)) .and(eq("external_id", externalId)) .allowFiltering() .limit(7); final List<Test> Tests = select(select, Test.class);
Log shown:
16:50:45.930 [main] DEBUG c.w.cassandra.dao.test.TestDAO - findByExternalId - companyId: 5-company_id - externalId: The-External-Id 16:50:45.930 [main] DEBUG c.w.cassandra.dao.test.TestDAO - findByExternalId - Query string: SELECT * FROM test WHERE company_id=? AND external_id=? LIMIT 7 ALLOW FILTERING; 16:50:45.933 [main] DEBUG c.w.cassandra.dao.test.TestDAO - findByExternalId - result from DB: 2 item(s) 17:29:18.995 [main] DEBUG c.w.cassandra.dao.test.TestDAO - Test@1306429814 -> id: ba001e98-07a6-44ed-b191-810c10faf059 - companyId: 5-company_id - locationId: 2-location_id - userId: 1-user_id - datetime: Wed Mar 01 06:00:00 EST 2000 - type: SHIFT_START - status: IMPORTED 17:29:18.995 [main] DEBUG c.w.cassandra.dao.test.TestDAO - Test@1216863787 -> id: 43026b3e-5746-4e78-a9c3-7635ad032bb0 - companyId: 5-company_id - locationId: 1-location_id - userId: 1-user_id - datetime: Tue Feb 29 06:00:00 EST 2000 - type: TRAINING_START - status: QUEUED
So, how it is possible ?
I have just made a test under DataStax Studio and it is working too.... and it triggers other questions related to in that case. How to be sure that all nodes have been queried and how to be sure about the order of the data, and how to be sure that we have newest data if one node did not answer or no need to answer due to the limit ? Then, does the secondary index is the safest way ?
Thank you for your answer.