Skip to content

Java driver composite columns

opuneet edited this page Jan 10, 2014 · 3 revisions

Consider the following hypothetical example. Here is a java pojo as a representation of a composite column.

public static class Population {
		
	@Component(ordinal=0) String state;
	@Component(ordinal=1) String city;
	@Component(ordinal=2) Integer zipcode;
		
	public Population() {
	}

	public Population(String state, String city, Integer zipcode) {
		this.state = state;
		this.city = city;
		this.zipcode = zipcode;
	}

	public String toString() {
		return "Population [" + state + ", " + city + ", " + zipcode + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((state == null) ? 0 : state.hashCode());
		result = prime * result + ((city == null) ? 0 : city.hashCode());
		result = prime * result + ((zipcode == null) ? 0 : zipcode.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) return true;
		if (obj == null)return false;
		if (getClass() != obj.getClass()) return false;
		Population other = (Population) obj;
		boolean equal = true;
		equal &= (state != null) ? (state.equals(other.state)) : other.state == null; 
		equal &= (city != null) ? (city.equals(other.city)) : other.city == null; 
		equal &= (zipcode != null) ? (zipcode.equals(other.zipcode)) : other.zipcode == null;
		return equal;
	}
		
	public Population clone() {
		return new Population(state, city, zipcode);
	}
}	

Say that we want to tabulate the population for various cities for various years. Consider the year as the row key. And each composite column is the city, and the column name is it's population for that year.

Consider this schema

Note here that key is the row key. Column1, Column2 and Column3 are the key components of the composite column that map directly to the components of the java bean with the same order. Value is the population for that year and that city.

Consider these rows for the years 2011 - 2014

Here are the example queries to create this table, insert this data and then query this data

Some basic setup

private AnnotatedCompositeSerializer<Population> compSerializer = 
    new AnnotatedCompositeSerializer<Population>(Population.class);

private ColumnFamily<Integer, Population> CF_POPULATION = 
    new ColumnFamily<Integer, Population>("population", 
                                           IntegerSerializer.get(), 
                                           compSerializer, 
                                           IntegerSerializer.get());

private Population NewYork = new Population("NY", "New York", 10000);
private Population SanDiego = new Population("CA", "San Diego", 20000);
private Population SanFrancisco = new Population("CA", "San Francisco", 30000);
private Population Seattle = new Population("WA", "Seattle", 40000);

Create table

keyspace.createColumnFamily(CF_POPULATION,     null);

Insert Rows

MutationBatch m = keyspace.prepareMutationBatch(); 
		
Random random = new Random();
		
for (int year = 2011; year <= 2014; year++) {
			
	m.withRow(CF_POPULATION, year)
		.putColumn(NewYork.clone(), random.nextInt(25000))
		.putColumn(SanDiego.clone(), random.nextInt(25000))
		.putColumn(SanFrancisco.clone(), random.nextInt(25000))
		.putColumn(Seattle.clone(), random.nextInt(25000));
}
		
m.execute();

Delete rows

MutationBatch m = keyspace.prepareMutationBatch(); 
		
for (int year = 2001; year <= 2014; year ++) {
	m.withRow(CF_POPULATION, year).delete();
}
		
m.execute();

Query Rows - single row reads

for (int year = 2001; year <= 2014; year++) {
    ColumnList<Population> result = keyspace.prepareQuery(CF_POPULATION)
                                    .getRow(year)
				    .execute().getResult();
			
for (Column<Population> p : result) {
	System.out.println(p.getName().toString() + " = " + p.getIntegerValue());
}

Query Single Row and Single Column

for (int year = 2001; year <= 2014; year++) {

    Column<Population> result = keyspace.prepareQuery(CF_POPULATION)
		.getRow(year)
		.getColumn(SanFrancisco.clone())
		.execute().getResult();

Query Single Row with Column Range

int year = 2011;

// ALL Cities in CA
ColumnList<Population> result = 
keyspace.prepareQuery(CF_POPULATION)
			.getRow(year)
			.withColumnRange(compSerializer.buildRange()
				         .withPrefix("CA")
				         .build())
			.execute().getResult();
		
// ALL Cities in CA starting from San Diego
result = keyspace.prepareQuery(CF_POPULATION)
			.getRow(year)
			.withColumnRange(compSerializer.buildRange()
				         .withPrefix("CA")
					 .greaterThan("San Diego")
					 .build())
			.execute().getResult();
		
// WA, Seattle with zip starting from 40000
result = keyspace.prepareQuery(CF_POPULATION)
			.getRow(year)
			.withColumnRange(compSerializer.buildRange()
					.withPrefix("WA")
					.withPrefix("Seattle")
					.withPrefix(40000)
					.build())
			.execute().getResult();

Row Slice query for all columns in each row

Rows<Integer, Population> result = keyspace.prepareQuery(CF_POPULATION)
				.getKeySlice(2011, 2012, 2013, 2014)
				.execute().getResult();

Row Slice query with Column Range specification

Rows<Integer, Population> 
result = keyspace.prepareQuery(CF_POPULATION)
				.getKeySlice(2011, 2012, 2013, 2014)
				.withColumnRange(compSerializer.buildRange()
						.withPrefix("CA")
                                                .build())
				.execute().getResult();
							
result = keyspace.prepareQuery(CF_POPULATION)
				 .getKeySlice(2011, 2012, 2013, 2014)
				 .withColumnRange(compSerializer.buildRange()
				 		  .withPrefix("CA")
				 		  .greaterThan("San Diego")
				 		  .build())
		 		  .execute().getResult();
									
result = keyspace.prepareQuery(CF_POPULATION)
				 .getKeySlice(2011, 2012, 2013, 2014)
				 .withColumnRange(compSerializer.buildRange()
				 		  .withPrefix("WA")
				 		  .withPrefix("Seattle")
				 		  .withPrefix(40000)
				 		  .build())
		 		  .execute().getResult();
Clone this wiki locally