簡體   English   中英

如何使用Astyanax和Composite列在Cassandra中執行遠程查詢

[英]How to execute ranged query in cassandra with astyanax and composite column

我正在使用cassandra和astyanax開發博客。 當然,這只是一種練習。

我以這種方式對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來說是個新手。

如果您的用例按照我認為的方式起作用,則可以修改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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM