查询前缀无法使用Astyanax工作的列

时间:2013-04-01 13:39:01

标签: cassandra astyanax

我的计划如下:

  • 时间戳
  • 设备ID
  • 设备名称
  • 设备所有者
  • 设备位置

我使用CQL创建了此列系列,并将主键定义为(TimeStamp,Device ID, Device Name)。通过可序列化对象,该对象具有DeviceID,名称和字段名称(存储Device OwnerDevice Location)的字段。我使用Astyanax插入了一些记录。

根据我的理解,行的列是通过将Device IDDevice Name和字段名称组合为列名来创建的,并将值作为该特定字段的值。 因此,对于特定时间戳和设备,列名称将采用模式(Device ID:Device Name: ...)

所以我相信我们可以使用这两个字段作为前缀来获取特定时间 - 设备组合的所有条目。

我使用以下查询来获取结果:

  RowSliceQuery<String, ApBaseData> query = adu.keyspace
  .prepareQuery(columnFamily)
  .getKeySlice(timeStamp)
  .withColumnRange(new RangeBuilder()
   .setStart(deviceID+deviceName+"_\u00000")
   .setEnd(deviceID+deviceName+"_\uffff")
   .setLimit(batch_size)
   .build());

但是在执行上述查询时,我得到以下异常:

  

BadRequestException:[host = localhost(127.0.0.1):9160,latency = 6(6),attempts = 1] InvalidRequestException(why:没有足够的字节来读取组件0的值)

@abhi此列系列中的数据如下:

    stime    |  devName  | devId | Owner | Location
  1361260800 | dev:01:02 |   1   | 1234  |    1  
  1361260800 | dev:02:03 |   2   | 34    |    2
  1361260800 | dev:05:06 |   1   | 12    |    1
  1361260800 | dev:03:02 |   2   | 56    |    3

我正在使用的java可串行java类是:

public class BaseData implements Serializable {
    private static final long serialVersionUID = 1L;
    @Component(ordinal = 0)
    private String devName;
    @Component(ordinal = 1)
    private int devID;
    @Component(ordinal = 2)
    private String field;
}

按照上面类的结构,我可以看到列族中的列为: Columne名称:dev \:01 \:02:1:location列值:00000001

仅供参考,使用astyanax 1.56.31

3 个答案:

答案 0 :(得分:1)

您可以将PlayOrm用于cassandra(我听说最新版本也在使用mongodb)。使用它可以创建一个实体并将@NoSqlPartitionByField注释添加到beginOfMonthTimestamp和deviceId列,另外还有timestamp列。然后,您可以查询分区,如此

PARTITIONS s('time',:partitionId)从TABLE中选择s作为s,其中s.deviceName ='mike'

只有在您确定分区不会超过数百万时,才可以。你可以拥有无​​限的分区。基本上,您可以使用beginOfMonth或beginOfWeek,具体取决于进入系统的内容的速度。

有更多信息

http://buffalosw.com/wiki/playorm-documentation/

答案 1 :(得分:1)

这里有两件事,
1.您在设备ID中使用“:”,Cassandra也将其用于复合列。因此,如果可以,请避免使用它 2.您的列名称为“dev \:01 \:02:1:location”,根据您的测试数据,它是devicename + deviceid + location。但是,您在查询中提供了deviceID + deviceName +“_ \ u00000”

答案 2 :(得分:0)

为了克服这个问题,我改变了在表格中存储数据的方式。我没有使用复合主键,而是更改了架构,以便只有一个主键和动态列。所以,现在我在stime上有主键,我的列名是由我的插入代码动态显式构造的。例如。 “dev \:01 \:02:1:location”与之前的方式相同,但这完全消除了对序列化对象的需求。这已经解决了我现在的问题。让我们看看它后来会出现什么问题。