2013-03-15 7 views
1

cassandra 및 astyanax를 사용하여 블로그를 개발 중입니다. 물론 운동 일뿐입니다.astandanax 및 복합 열을 사용하여 cassandra에서 원거리 쿼리를 실행하는 방법

나는 이런 식으로 CF_POST_INFO 열 가족을 모델로 한 :

private static class PostAttribute { 

    @Component(ordinal = 0) 
    UUID postId; 

    @Component(ordinal = 1) 
    String category; 

    @Component 
    String name; 

    public PostAttribute() {} 

    private PostAttribute(UUID postId, String category, String name) { 
     this.postId = postId; 
     this.category = category; 
     this.name = name; 
    } 

    public static PostAttribute of(UUID postId, String category, String name) { 
     return new PostAttribute(postId, category, name); 
    } 
} 

    private static AnnotatedCompositeSerializer<PostAttribute> postSerializer = new AnnotatedCompositeSerializer<>(PostAttribute.class); 

private static final ColumnFamily<String, PostAttribute> CF_POST_INFO = 
     ColumnFamily.newColumnFamily("post_info", StringSerializer.get(), postSerializer); 

그리고 게시물이 방법으로 저장됩니다

 MutationBatch m = keyspace().prepareMutationBatch(); 

    ColumnListMutation<PostAttribute> clm = m.withRow(CF_POST_INFO, "posts") 
      .putColumn(PostAttribute.of(post.getId(), "author", "id"), post.getAuthor().getId().get()) 
      .putColumn(PostAttribute.of(post.getId(), "author", "name"), post.getAuthor().getName()) 
      .putColumn(PostAttribute.of(post.getId(), "meta", "title"), post.getTitle()) 
      .putColumn(PostAttribute.of(post.getId(), "meta", "pubDate"), post.getPublishingDate().toDate()); 

    for(String tag : post.getTags()) { 
     clm.putColumn(PostAttribute.of(post.getId(), "tags", tag), (String) null); 
    } 

    for(String category : post.getCategories()) { 
     clm.putColumn(PostAttribute.of(post.getId(), "categories", category), (String)null); 
    } 

아이디어는 시간의 버킷과 같은 몇 가지 행을하는 것입니다 (예 : 한 달 또는 한 해에 한 행).

예를 들어 최근 5 개의 게시물을 가져 오려면 어떻게해야할까요? 게시물 ID (UUID)를 기반으로 분노 쿼리를 실행할 수 있지만 가져 오기 위해 다른 쿼리를 수행하지 않고 사용 가능한 게시물 ID를 알지 못합니다. 카산드라 모범 사례는 무엇입니까?

데이터 모델에 대한 모든 제안은 물론 환영합니다. 나는 cassandra에게 매우 초보자입니다.

답변

2

유스 케이스가 작동한다고 생각하는 경우 PostAttribute를 수정하여 첫 번째 구성 요소를 시계열 데이터로 저장할 수있는 방식으로 TimeUUID를 사용하면 가장 오래된 5 개를 쉽게 가져올 수 있습니다. 또는 최신 5 표준 기술을 사용합니다. 어쨌든 ... 이미 복합체를 사용하고 있다면 다중 열을 만들 필요가 없기 때문에 나에게 어떻게 보이는지 샘플을 얻을 수 있습니다.

public class PostInfo { 
    @Component(ordinal = 0) 
    protected UUID timeUuid; 

    @Component(ordinal = 1) 
    protected UUID postId; 

    @Component(ordinal = 2) 
    protected String category; 

    @Component(ordinal = 3) 
    protected String name; 

    @Component(ordinal = 4) 
    protected UUID authorId; 

    @Component(ordinal = 5) 
    protected String authorName; 

    @Component(ordinal = 6) 
    protected String title; 

    @Component(ordinal = 7) 
    protected Date published; 

    public PostInfo() {} 

    private PostInfo(final UUID postId, final String category, final String name, final UUID authorId, final String authorName, final String title, final Date published) { 
     this.timeUuid = TimeUUIDUtils.getUniqueTimeUUIDinMillis(); 
     this.postId = postId; 
     this.category = category; 
     this.name = name; 
     this.authorId = authorId; 
     this.authorName = authorName; 
     this.title = title; 
     this.published = published; 
    } 

    public static PostInfo of(final UUID postId, final String category, final String name, final UUID authorId, final String authorName, final String title, final Date published) { 
     return new PostInfo(postId, category, name, authorId, authorName, title, published); 
    } 
} 

    private static AnnotatedCompositeSerializer<PostInfo> postInfoSerializer = new AnnotatedCompositeSerializer<>(PostInfo.class); 

private static final ColumnFamily<String, PostInfo> CF_POSTS_TIMELINE = 
     ColumnFamily.newColumnFamily("post_info", StringSerializer.get(), postInfoSerializer); 

당신은 이런 식으로 저장해야합니다

MutationBatch m = keyspace().prepareMutationBatch(); 

ColumnListMutation<PostInfo> clm = m.withRow(CF_POSTS_TIMELINE, "all" /* or whatever makes sense for you such as year or month or whatever */) 
     .putColumn(PostInfo.of(post.getId(), post.getCategory(), post.getName(), post.getAuthor().getId(), post.getAuthor().getName(), post.getTitle(), post.getPublishedOn()), /* maybe just null bytes as column value */) 
m.execute(); 

그런 다음이 같은 조회 수 :

OperationResult<ColumnList<PostInfo>> result = getKeyspace() 
    .prepareQuery(CF_POSTS_TIMELINE) 
    .getKey("all" /* or whatever makes sense like month, year, etc */) 
    .withColumnRange(new RangeBuilder() 
     .setLimit(5) 
     .setReversed(true) 
     .build()) 
    .execute(); 
ColumnList<PostInfo> columns = result.getResult(); 
for (Column<PostInfo> column : columns) { 
    // do what you need here 
} 
+0

감사합니다, 그래 내가 찾고 있었던 것입니다. –

+1

문제 없습니다. 기꺼이 봉사하겠다. –