2014-06-10 1 views
5

J'utilise Spring Data Cassandra 1.0.0. J'ai réussi à persister et relire mon entité. Cependant, maintenant je veux faire une requête qui ne renvoie que 1 champ de l'entité.Comment faire une requête pour seulement 1 champ avec Spring Data Cassandra?

C'est ce que j'ai essayé:

public Optional<DateTime> getTimeOfOldestIntervalTrafficDataMessage(MessageSource messageSource, IntegrationPeriod integrationPeriod, TrafficDataType trafficDataType) 
{ 
    Select select = QueryBuilder.select("message_time").from("messages", "data_message"); 
    select.where(QueryBuilder.eq("message_source_id", messageSource.getId().getId())) 
      .and(QueryBuilder.eq("data_type", trafficDataType.name())) 
      .and(QueryBuilder.eq("integration_period", integrationPeriod.name())); 

    List<Date> result = cassandraOperations.select(select, Date.class); 
    if (result.size() > 0) 
    { 
     return Optional.of(new DateTime(FluentIterable.from(result).toSortedSet(Ordering.natural()).first())); 
    } 
    else 
    { 
     return Optional.absent(); 
    } 
} 

cassandraOperations est une instance CassandraTemplate.

Je sélectionne donc uniquement message_time à partir du tableau data_message. Ceci est une colonne timestamp, donc je passe dans un Date.class la méthode select(), mais cela donne l'exception suivante:

org.springframework.data.mapping.model.MappingException: No mapping metadata found for java.util.Date 
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.readRow(MappingCassandraConverter.java:111) 
    at org.springframework.data.cassandra.convert.MappingCassandraConverter.read(MappingCassandraConverter.java:202) 
    at org.springframework.data.cassandra.core.CassandraConverterRowCallback.doWith(CassandraConverterRowCallback.java:47) 
    at org.springframework.data.cassandra.core.CassandraTemplate.select(CassandraTemplate.java:455) 
    at org.springframework.data.cassandra.core.CassandraTemplate.select(CassandraTemplate.java:253) 
    at com.mycomp.app.infrastructure.cassandra.CassandraMessageRepository.getTimeOfOldestIntervalTrafficDataMessage(CassandraMessageRepository.java:130) 

Comment dois-je interroger pour seulement 1 terrain? PS: Si vous voulez connaître une manière plus performante de faire cette requête, je serais heureux de l'entendre aussi.

Répondre

5

trouvé comment faire:

public Optional<DateTime> getTimeOfOldestIntervalTrafficDataMessage(MessageSource messageSource, IntegrationPeriod integrationPeriod, TrafficDataType trafficDataType) 
    { 
     Select select = QueryBuilder.select("message_time").from("messages", "data_message"); 
     select.where(QueryBuilder.eq("message_source_id", messageSource.getId().getId())) 
       .and(QueryBuilder.eq("traffic_data_type", trafficDataType.name())) 
       .and(QueryBuilder.eq("integration_period", integrationPeriod.name())); 
     select.orderBy(QueryBuilder.asc("message_time")); 
     select.limit(1); 

     Date date = m_cassandraOperations.queryForObject(select, Date.class); 
     if(date != null) 
     { 
      Optional<DateTime> result = Optional.of(new DateTime(date)); 
      logger.debug("oldest interval: {} ({}/{}/{})", result, messageSource.getName(), trafficDataType, integrationPeriod); 
      return result; 
     } 
     else 
     { 
      return Optional.absent(); 
     } 
    } 

fonction queryForObject() est le chemin à parcourir. J'ai aussi utilisé la commande et la limite pour que Cassandra fasse le travail de trouver ce dont j'ai besoin.

+1

N'hésitez pas à marquer votre réponse comme résolue. – Ztyx

+0

C'est exact. –

+0

Cassandra Operations a une méthode ---- cassandraOperations.selectOne (statement.toString(), ABC.class), nous pouvons l'utiliser aussi – denzal

Questions connexes