天天看點

使用storm統計英文版<<聖經>>的詞頻

我估計自己是瘋掉了.....

剛入門storm,就先硬生生的來杠這部著作......

我先擦一把汗哈,然後呢,整個流程需要五個步驟,希望大家都可以得到屬于自己的統計資料

使用storm統計英文版<<聖經>>的詞頻
使用storm統計英文版<<聖經>>的詞頻

1.下載下傳聖經英文版,并修改一部分内容,例如标點

2.參考我的另一篇部落格,那裡面幾乎是源碼(隻改兩個類)

3.修改源碼

4.準備枕頭

5.擡頭看結果

一.下載下傳并修改 下載下傳位址:http://www.o-bible.com/gb/dlb.html 修改:主要是外國人的習慣可能會使我們根據空格統計時把用标點符号連接配接的兩個單詞當做一個單詞

  • 把所有逗号, 替換為""
  • 把所有句号. 替換為" "(注意有空格)
  • 把所有分号; 替換為""
  • 把所有問号? 替換為""
  • 把所有冒号: 替換為""
  • 把所有左括号( 替換為" "(注意有空格)
  • 把所有右括号) 替換為""(沒有空格)
  • (進階項):替換所有數字為 ""
  • (進階項):替換所有表述為 "章節"含義的單詞為""

二.參考部落格

請先參考我的部落格:http://blog.csdn.net/weixin_35757704/article/details/77246313

這篇部落格思路很簡單,十分基礎,參考它是因為我的這個就是在那篇部落格源碼的基礎上改進來的

三.修改源碼

這裡面有具體的代碼,我們隻需要簡單修改兩個類就可以:

CreateSpout 修改

import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values;
import backtype.storm.utils.Utils;
import org.joda.time.DateTime;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Map;

/**
 * 建立資料源
 */
public class CreateSpout extends BaseRichSpout {

    private SpoutOutputCollector collector;
    private String[] sentences = null; //為資料的總容量
    String pathname;
    File filename;
    InputStreamReader reader;
    BufferedReader br;

    private String read() {

        try {
            String line = "";
            line = br.readLine();
            if (line != null) {
                return line;
            } else {
                Utils.sleep(200000000);
            }
        } catch (Exception e) {
        }
        return "null";
    }

    @Override
    public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
        this.collector = spoutOutputCollector;
        try {
            pathname = "C:\\storm\\storm_Pro\\kjv.txt";
            filename = new File(pathname);
            reader = new InputStreamReader(
                    new FileInputStream(filename));
            br = new BufferedReader(reader);

        } catch (Exception e) {

        }
    }

    @Override
    public void nextTuple() {
        sentences = new String[]{read()};
        /*storm會循環的調用這個方法*/
        /*線程進行休眠,10s發送一次資料,在這10s内,讓其餘工作進行*/
        Utils.sleep(100);
        //獲得資料源
        System.out.println(new DateTime().toString("HH:mm:ss") + "--------------CreateSpout 開始發送資料----------");
        this.collector.emit(new Values(sentences));
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
        outputFieldsDeclarer.declare(new Fields("sentence"));
    }

}

           

對這個類的修改,就是把資料源修改一下,從本地檔案 kjv.txt讀取,這也是<<聖經>>英文版的txt檔案.大家也可以從其他地方下載下傳.

PrintBolt 修改

import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Tuple;
import backtype.storm.utils.Utils;
import org.joda.time.DateTime;

import java.util.Map;

public class PrintBolt extends BaseRichBolt {
    @Override
    public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
    }

    @Override
    public void execute(Tuple input) {

        System.out.println(new DateTime().toString("HH:mm:ss") + "--------------------final bolt 開始運作--------------------");
        Map<String, Integer> counts = (Map<String, Integer>) input.getValue(0);
        /*最後一個階段,可以持久到mysql等資料庫中*/
        System.out.println(justForm(20 - 8) + "key" + justForm(20 - 8) + "      " + "value");
       
	try {
	   	 System.out.println("/");//與之前的列印資訊分隔,直覺的得到結果
 		for (Map.Entry<String, Integer> kv : counts.entrySet()) { /*這裡的justForm()函數是為了保證格式一緻*/
                System.out.println(kv.getKey() + justForm(kv.getKey().length()) + " 頻數 : " + kv.getValue());
            }
       	} catch (Exception e) {
            System.out.println("/得到一個錯誤的值");
        }
	try {
            Utils.sleep(60000);
        }catch (Exception e){

        }

    }

    private String justForm(int length) {
        for (int i = 0; i < 20 - length; i++) {
            System.out.print(" ");
        }
        return "";
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {

    }
}
           

對結果列印的代碼進行修改是因為我們都知道,這種事情不是一時半會能完成的,是以這裡設定一個等待的線程,不用實時的列印結果,隻需要1分鐘列印一次就好,不過我測試了一下,虛拟機win8.1+8G記憶體+SSD+i7-7700HQ的兩個核心,也使用了20+分鐘,下圖是我在主控端上截取的當時的資料:

使用storm統計英文版&lt;&lt;聖經&gt;&gt;的詞頻

四.準備枕頭

點一下運作,能正常跑兩分鐘,觀察是不是死循環,如果一切正常,就可以倒頭睡覺了

五.擡頭看結果

下圖有點恐怖,密集型恐懼症患者請捂臉.....

我的編譯器是Intellij IDEA,它可以在控制台儲存相當多的資料,是以可以都得到,其他的編輯器我就不是很了解了,如果為了以防萬一,可以直接列印到本地檔案中

而且如果你能夠觀察到右側滑塊的位置的話,那麼你就可以知道為什麼會有第四步了.....

使用storm統計英文版&lt;&lt;聖經&gt;&gt;的詞頻

大家可能注意到了,有許多頻數隻是1,大緻翻譯就是不同篇章的第1節,第二節等,是以這個篩選條件是有很大的改進空間的.

期待大家可以得到更好的篩選結果.大笑

繼續閱讀

繼續閱讀