首先,我得说明这篇博客基本上就是<
用户在查看网站的文章时,文章当然是按顺序排列的(这个顺序怎么计算呢?我们把文章发表的时间求出来,这个时间就是离1970年的那个秒数,同时,文章每被投票一次,再那个时间的基础上加上一个常量。最后按照所有文章的总得分来排序)。
当然,我也可以就按照发表时间排序。http://doc.redisfans.com/
private static final int ONE_WEEK_IN_SECONDS = 7 * 86400;
public String postArticle(Jedis conn, String user, String title, String link) {
//获得最新的id
String articleId = String.valueOf(conn.incr("article:"));
String voted = "voted:" + articleId;
//自己给自己的文章投票
conn.sadd(voted, user);
//一篇文章只有在发布七天内才能投票
conn.expire(voted, ONE_WEEK_IN_SECONDS);
//保存文章到散列表
long now = System.currentTimeMillis() / 1000;
String article = "article:" + articleId;
HashMap articleData = new HashMap();
articleData.put("title", title);
articleData.put("link", link);
articleData.put("user", user);
articleData.put("now", String.valueOf(now));
articleData.put("votes", "1"); //自己投的第一票
conn.hmset(article, articleData);
//加了一个数据域 key是score: member是文章 score是文章的得分
//发布的时候 默认作者本人为文章投票
conn.zadd("score:", now + VOTE_SCORE, article);
//加了一个数据域 key是time: member是文章 score是文章的发布时间
conn.zadd("time:", now, article);
return articleId;
}
//每一票对应的常量
private static final int VOTE_SCORE = 432;
public void articleVote(Jedis conn, String user, String article) {
long cutoff = (System.currentTimeMillis() / 1000) - ONE_WEEK_IN_SECONDS;
//cutoff之前的发布的文章 就不能再投票了
if (conn.zscore("time:", article) < cutoff){
return;
}
String articleId = article.substring(article.indexOf(':') + 1);
//查看user是否给这篇文章投过票
//set里面的key是唯一的 如果 sadd返回0 表示set里已经有数据了
//如果返回1表示还没有这个数据
if (conn.sadd("voted:" + articleId, user) == 1) {
conn.zincrby("score:", VOTE_SCORE, article);
conn.hincrBy(article, "votes", 1l);
}
}
public void addGroups(Jedis conn, String articleId, String[] toAdd) {
String article = "article:" + articleId;
for (String group : toAdd) {
conn.sadd("group:" + group, article);
}
}
public List
public List> getGroupArticles(Jedis conn, String group, int page, String order) {
String key = order + group;
if (!conn.exists(key)) { //先查看缓存中有没有
ZParams params = new ZParams().aggregate(ZParams.Aggregate.MAX);
conn.zinterstore(key, params, "group:" + group, order);
conn.expire(key, 60); //放进缓存 60s后过期
}
return getArticles(conn, page, key);
}
这里现在出现问题了
zinterstore简单的说就是关系型数据库里面的关联表操作
左边的"表"存放的是programing这个组下的文章信息public class ZParams {
public enum Aggregate {
SUM, MIN, MAX; //猜一下sum是什么意思
public final byte[] raw;
Aggregate() {
raw = SafeEncoder.encode(name());
}
}
// .....
}
//每一票对应的常量
private static final int VOTE_SCORE = 432;
public void articleOppose(Jedis conn, String user, String article) {
long cutoff = (System.currentTimeMillis() / 1000) - ONE_WEEK_IN_SECONDS;
//cutoff之前的发布的文章 就不能再投票了
if (conn.zscore("time:", article) < cutoff){
return;
}
String articleId = article.substring(article.indexOf(':') + 1);
//查看user是否给这篇文章投过票
//set里面的key是唯一的 如果 sadd返回0 表示set里已经有数据了
//如果返回1表示还没有这个数据
if (conn.sadd("oppose:" + articleId, user) == 1) {
conn.zincrby("score:", -VOTE_SCORE, article);
conn.hincrBy(article, "votes", -1l);
}
}
搞定!
/////////////////////////////////////////////////////////
以下为2016-10-19日更新
我们查看getArticles的代码,分析一下,
第一次交互和redis交互,获得了id名
后面还有25次交互获得了文章的详细信息
一共交互了26次
那么有没有更好的方法呢?
public List> getArticles(Jedis conn, int page, String order) {
int start = (page - 1) * ARTICLES_PER_PAGE;
int end = start + ARTICLES_PER_PAGE - 1;
Set ids = conn.zrevrange(order, start, end);
Map>> map=uesPipeline(conn,ids);
List> articles = new ArrayList>();
for (Entry>> entry : map.entrySet()){
String id=entry.getKey();
Map article=entry.getValue().get();
article.put("id", id);
articles.add(article);
}
return articles;
}
private Map>> uesPipeline(Jedis conn, Set ids) {
Pipeline p=conn.pipelined();
Map>> map =
new HashMap>>();
for (String id : ids){
Response> articleData= p.hgetAll(id);
map.put(id, articleData);
}
p.sync();
return map;
}
package redisinaction;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ZParams;
import java.util.*;
public class Chapter01 {
private static final int ONE_WEEK_IN_SECONDS = 7 * 86400;
private static final int VOTE_SCORE = 432;
private static final int ARTICLES_PER_PAGE = 25;
public String postArticle(Jedis conn, String user, String title, String link) {
String articleId = String.valueOf(conn.incr("article:"));
String voted = "voted:" + articleId;
conn.sadd(voted, user);
conn.expire(voted, ONE_WEEK_IN_SECONDS);
long now = System.currentTimeMillis() / 1000;
String article = "article:" + articleId;
HashMap articleData = new HashMap();
articleData.put("title", title);
articleData.put("link", link);
articleData.put("user", user);
articleData.put("now", String.valueOf(now));
articleData.put("votes", "1");
conn.hmset(article, articleData);
conn.zadd("score:", now + VOTE_SCORE, article);
conn.zadd("time:", now, article);
return articleId;
}
public void articleVote(Jedis conn, String user, String article) {
long cutoff = (System.currentTimeMillis() / 1000) - ONE_WEEK_IN_SECONDS;
if (conn.zscore("time:", article) < cutoff){
return;
}
String articleId = article.substring(article.indexOf(':') + 1);
if (conn.sadd("voted:" + articleId, user) == 1) {
conn.zincrby("score:", VOTE_SCORE, article);
conn.hincrBy(article, "votes", 1l);
}
}
public List> getArticles(Jedis conn, int page) {
return getArticles(conn, page, "score:");
}
public List> getArticles(Jedis conn, int page, String order) {
int start = (page - 1) * ARTICLES_PER_PAGE;
int end = start + ARTICLES_PER_PAGE - 1;
Set ids = conn.zrevrange(order, start, end);
List> articles = new ArrayList>();
for (String id : ids){
Map articleData = conn.hgetAll(id);
articleData.put("id", id);
articles.add(articleData);
}
return articles;
}
public void addGroups(Jedis conn, String articleId, String[] toAdd) {
String article = "article:" + articleId;
for (String group : toAdd) {
conn.sadd("group:" + group, article);
}
}
public List> getGroupArticles(Jedis conn, String group, int page) {
return getGroupArticles(conn, group, page, "score:");
}
public List> getGroupArticles(Jedis conn, String group, int page, String order) {
String key = order + group;
if (!conn.exists(key)) {
ZParams params = new ZParams().aggregate(ZParams.Aggregate.MAX);
conn.zinterstore(key, params, "group:" + group, order);
conn.expire(key, 60);
}
return getArticles(conn, page, key);
}
}
package redisinaction;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.junit.BeforeClass;
import org.junit.Test;
import redis.clients.jedis.Jedis;
/**
* This class is used for ...
* @author dlf([email protected])
* @version 1.0, 2016年10月17日 下午10:15:58
*/
public class Chapter01Test {
Jedis conn = null;
@BeforeClass
public void initConn(){
System.out.println("test before");
conn = new Jedis("10.150.0.80");
conn.auth("dlf123123");
}
//@Test
public void testPostArticle(){
Chapter01 c= new Chapter01();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date2=sdf.format(date);
String articleId = c.postArticle(conn, "dlf", "A title"+date2, "http://www.google.com");
System.out.println(articleId);
}
@Test
public void testGetAllArticles(){
List> result= new Chapter01().getArticles(conn, 1);
for(Map map:result){
Iterator> iterator= map.entrySet().iterator();
while(iterator.hasNext()){
Entry entry= iterator.next();
System.out.print(entry.getKey()+":"+entry.getValue()+" ");
}
System.out.println("");
}
}
}