0

在设计用于推文分析的系统时,我需要建议。

目标:对于给定的主题标签,找出与其他主题标签同时出现的频率。找出每小时模式。我们应该能够回答这种格式的查询:对于给定的日期(比如 2013 年 4 月 13 日)和给定的一小时时间段(比如下午 3:00-4:00),前 5 个同时发生的事件是什么带有“#iPhone”的标签。

我的方法:我正在使用“twitter4j”库来访问 twitter 数据。我可以为一个电话查询并获得 100 条推文(推特只允许这么多)。我可以提取时间和其他相关数据。我计划有一个线程,每 5 分钟查询一次 twitter。这是对观察者每小时模式进行的。这是我感到震惊的地方:我应该如何将这些信息存储在数据库中?我是否应该维护一个哈希图,其中键为和值作为“#iPhone”出现的频率。或者我应该将未聚合的数据直接存储在数据库中吗?向观察者每小时模式查询“twitter”的最佳方式是什么?我应该将时间以“纪元”格式存储在 DB 中还是作为日期一列和小时作为 DB 中的另一列?

非常感谢您的宝贵意见。

4

3 回答 3

2

我建议您在 Twitter 中使用 Streaming API。这将允许您保持与 twitter 的持久 HTTP 连接,以便您可以搜索推文。Twitter 建议将Streaming API用于推文分析类型的应用程序。

但是您必须对某些数据进行预处理,以便分析更快。还要查看twitter4j 固有的 Streaming API支持。

例如,请查看以下Github 代码

于 2013-04-13T18:30:00.973 回答
1

正如ay89所说,使用key-tag和value-freq,在存储到数据库之前聚合,并使用epoch。

此外,由于这是一个多线程程序,您有两个同步选项:

选项 1 是使用ConcurrentHashMap。当聚合器运行时,它将使用:

(for Key key : hashMap.keySet()) {
    Database.save(key, hashMap.get(key));
    hashMap.replace(key, 0);
}

换句话说,在将标签写入数据库后,将其频率设置为 0。添加推文数据的方法将使用

public void increment(Key key) {
    boolean done = false;
    while(!done) {
        int current = hashMap.get(key);
        int newValue = current + 1;
        done = hashMap.replace(key, current, newValue);
    }
}

这是一种增加频率的线程安全方式。

选项 2 可能更有意义。您的聚合器将用新实例替换哈希图。

class DataStore {
    Map map = new HashMap();

    public void add(Key key, Value value) {
        // called by the method querying tweet data
    }

    public void aggregate() {
       // called by the aggregator thread every five minutes
       Map oldMap = map;
       map = new HashMap();
       DataBase.save(oldMap);
   }
}

底线是您不想在聚合器将哈希图保存到数据库时以不受控制的方式修改哈希图。第二个选项更简单,因为它只是为查询线程创建一个新的哈希图以进行修改,而聚合器将旧的哈希图保存到数据库中。

于 2013-04-13T18:16:16.223 回答
0

由于您只需要检索频率,因此最好将其存储在哈希中,(键 - 标记,值 - 频率)因为将非聚合数据存储在 db 中会占用更多空间(并且主要用于不需要的信息)和最终你将不得不在以后聚合它。

纪元时间是存储时间的好方法。因为您可以使用它来根据时区对其进行本地化,如果以后需要的话。

于 2013-04-13T11:22:56.210 回答