2014-09-12 3 views
0

현재 공식 Datastax 드라이버 (V2.0)를 사용하여 매우 기본적인 CQL 액세스 계층을 작성 중이며 매개 변수 값을 전달하는 데 어려움을 겪고 있습니다.cassandra-driver-core : 목록 화 된 값을 매개 변수화 된 SimpleStatement에 전달합니다.

여기

열 가족 (간체) 예를 들어

USE myKeyspace; 

CREATE TABLE MyTable (
    myId timeuuid, 
    myTypeId int, 
    myVal varchar, 
    PRIMARY_KEY(myId, myTypeId) 
); 

CREATE INDEX MyTable_myTypeID 
    ON MyTable(myTypeId); 

기본 개념은 여러 값 일부 이벤트 데이터를 저장한다 ("이벤트"당)이다, 즉 내가 사용하고 이유 결합 된 PK. 모든 이벤트에는 시간 기반 UUID가 있으며 typeId 당 여러 항목이있을 수 있습니다. 모델링 관점에서도 의미가 있습니까?

내가 지금하려는 것은 'typeIds'를 선택하여 이벤트에 대한 항목 만 가져 오는 것입니다.

public void myQueryCode() { 

    Cluster.Builder builder = Cluster.builder(); 
    builder.withPort(9142); 
    builder.addContactPoints("127.0.0.1"); 
    cluster = builder.build(); 
    Session session = cluster.connect("myKeyspace"); 

    List<Integer> typeFilter = new ArrayList<>(); 
    typeFilter.add(1); 
    typeFilter.add(2); 

    Statement stmt = new SimpleStatement( 
     "SELECT * FROM MyTable where myId = ?" + 
     " AND myTypeId IN (?,?)" + 
     " ALLOW FILTERING", 
     UUID.randomUUID(), 
     typeFilter); 

    ResultSet result = session.execute(stmt); 

    // do something with results 
} 

그러나 Statement 값의 serialization에서 예외가 발생했습니다.

com.datastax.driver.core.exceptions.InvalidQueryException: Expected 4 or 0 byte int (8) 
at com.datastax.driver.core.exceptions.InvalidQueryException.copy(InvalidQueryException.java:35) 
at com.datastax.driver.core.DefaultResultSetFuture.extractCauseFromExecutionException(DefaultResultSetFuture.java:256) 
at com.datastax.driver.core.DefaultResultSetFuture.getUninterruptibly(DefaultResultSetFuture.java:172) 
at com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:52) 

나는, 드라이버가 매개 변수를 취하고 두 번째 매개 변수로 목록을 전달에 잘 모르겠어요,하지만 어쩌면 그 컬렉션 타입 컬럼에 삽입에만 적합?

답변

2

두 번째 매개 변수에 강제로 삽입되고 이로 인해 InvalidQueryException이 발생합니다. 매개 변수 typeFilter 드라이버가 다음 매개 변수를 2로 목록 컬렉션 개체를 배치하려고 시도 목록이며, 일이 남았습니다 이동하기 때문에

Statement stmt = new SimpleStatement( 
     "SELECT * FROM MyTable where myId = ?#1" + 
     " AND myTypeId IN (?#2,?#3)" + 
     " ALLOW FILTERING", 
     #1 UUID.randomUUID(), 
     #2 typeFilter); 

. 이것은 (준비없이)이 같은 명령문을 실행할 때 드라이버가 유형을 확인할 수 없기 때문입니다. Comment in code. 대신에 전달한 경우

Statement stmt = new SimpleStatement( 
      "SELECT * FROM MyTable where myId = ?#1" + 
      " AND myTypeId IN (?#2,?#3)" + 
      " ALLOW FILTERING", 
      #1 UUID.randomUUID(), 
      #2 typeFilter.get(0) 
      #3 typeFilter.get(1)); 

괜찮을 것입니다. 또는 문장을 먼저 준비했다면 컴파일 타임 오류가 발생했을 것입니다.

+0

필자가 생각하기에, 다양한 type 필터 목록 길이를 처리 할 때 까다로운 일이 생길 수 있습니다. 그런 다음 모든 쿼리 매개 변수 값을 Object 배열에 넣고 매개 변수 목록으로 SimpleQuery에 전달해야합니다 (원래 코드는 자리 표시 자/와일드 카드 수를 조정합니다. 그러나 인덱스 또는 별칭 기반 매개 변수 처리 및 유형별 setter를 사용하는 전통적인 PreparedStatement처럼 처리하는 BoundStatement를 사용하는 것이 더 좋습니다. 유일한 문제는 남아 있습니다 : 나는 PK에 타입을 가지고 싶습니다만, Cassandra 2.0은 PK 컬럼의 "IN"절을 지원하지 않습니다. – DoNuT

1

첫 번째 질문에 대한 대답으로, "여러 값 (이벤트")이있는 일부 이벤트 데이터를 저장하는 것이 모델링 관점에서 의미가 있는지, 그 이유는 내가 결합 된 PK를 사용하고 있기 때문입니다. 모든 이벤트에는 시간이 있습니다 기반 UUID, typeId 당 여러 항목이있을 수 있습니다. "예. 이는 카산드라 팀이 음악 서비스의 데이터 모델링 예 : http://www.datastax.com/documentation/cql/3.1/cql/ddl/ddl_music_service_c.html에서 사용하는 시나리오와 비슷한 시나리오입니다.

내가 명령 줄에 예를 할 수 있기 때문에 코드에서 사소한 결함에 대한

봐 :

 
CREATE TABLE MyTable (
    myId timeuuid, 
    myTypeId int, 
    myVal varchar, 
    PRIMARY_KEY(myId, myTypeId) 
); 
CREATE INDEX MyTable_myTypeID 
    ON MyTable(myTypeId); 
insert into mytable(myid, mytypeid, myval) VALUES (d2177dd0-eaa2-11de-a572-001b779c76e3, 100, 'somechar') 
insert into mytable(myid, mytypeid, myval) VALUES (d2177dd0-eaa2-11de-a572-001b779c76e3, 200, 'anotherchar') 
SELECT * FROM MyTable where myId = d2177dd0-eaa2-11de-a572-001b779c76e3 AND myTypeId IN (100,200) ALLOW FILTERING; 

출력은 : 당신은 당신이 전달하는 목록이다 올바른지

 
myid         | mytypeid | myval 
--------------------------------------+----------+------------- 
d2177dd0-eaa2-11de-a572-001b779c76e3 |  100 | somechar 
d2177dd0-eaa2-11de-a572-001b779c76e3 |  200 | anotherchar 
+0

예, 코드 결함이었습니다. 1 UUID와 크기 2의 목록이 3 개의 매개 변수 (실제로 1xUUID + 1x 목록 유형)를 전달하여 데이터 유형이 일치하지 않는다는 것을 의미하지는 않습니다 (두 번째 매개 변수는 정수이며 목록이 없음). – DoNuT