商品订单频繁项集Spout实现

一 需求
通过OrderSpout读取Redis中的订单数据,以供拓扑结构下游的Bolt使用。
通过CommandSpout实现统计支持度和置信度。

二 OrderSpout实现
package com.hust.grid.leesf.ordertest.spout;
import java.util.Map;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.hust.grid.leesf.ordertest.common.ConfKeys;
import com.hust.grid.leesf.ordertest.common.FieldNames;
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 redis.clients.jedis.Jedis;
/**
 * 数据源,从redis读取订单
 *
 *
 */
public class OrderSpout extends BaseRichSpout {
     private static final long serialVersionUID = 1L;
     private SpoutOutputCollector collector;
     private Jedis jedis;
     private String host;
     private int port;
     public void open(@SuppressWarnings("rawtypes") Map conf, TopologyContext context, SpoutOutputCollector collector) {
           this.collector = collector;
           this.host = conf.get(ConfKeys.REDIS_HOST).toString();
           this.port = Integer.parseInt(conf.get(ConfKeys.REDIS_PORT).toString());
           connectToRedis();
     }
     private void connectToRedis() {
           jedis = new Jedis(host, port);
           jedis.connect();
     }
     public void nextTuple() {
           String content = jedis.rpop("orders"); // 获取一条订单数据
           if (null == content || "nil".equals(content)) { // 若无,则等待300ms
                try {
                     Thread.sleep(300);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
           } else { // 对订单数据进行转化
                JSONObject object = (JSONObject) JSONValue.parse(content);
                String id = object.get(FieldNames.ID).toString(); // 获取ID
                JSONArray items = (JSONArray) object.get(FieldNames.ITEMS); // 获取订单中的商品
                for (Object obj : items) { // 遍历订单中的商品
                     JSONObject item = (JSONObject) obj;
                     String name = item.get(FieldNames.NAME).toString(); // 商品名称
                     int count = Integer.parseInt(item.get(FieldNames.COUNT).toString()); // 商品数量
                     collector.emit(new Values(id, name, count)); // 发射订单号、商品名称、商品数量
                     if (jedis.hexists("itemCounts", name)) { // redis中存在name字段
                           jedis.hincrBy("itemCounts", name, 1); // 商品对应数量(订单中多个商品当作1个)增加1
                     } else { // redis中不存在name字段
                           jedis.hset("itemCounts", name, "1"); // 将name字段的值(商品数量)设置为1
                     }
                }
           }
     }
     public void declareOutputFields(OutputFieldsDeclarer declarer) {
           // 声明发射元组字段
           declarer.declare(new Fields(FieldNames.ID, FieldNames.NAME, FieldNames.COUNT));
     }
}

三 CommandSpout实现
package com.hust.grid.leesf.ordertest.spout;

import java.util.Map;

import com.hust.grid.leesf.ordertest.common.FieldNames;

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;

/**
* 统计支持度和置信度
*
* @author leesf
*/
public class CommandSpout extends BaseRichSpout {
    private static final long serialVersionUID = 1L;

    private SpoutOutputCollector collector;

    public void open(@SuppressWarnings("rawtypes") Map conf, TopologyContext context, SpoutOutputCollector collector) {
        this.collector = collector;
    }

    public void nextTuple() {
        // 休眠5S后发射“statistics”
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        collector.emit(new Values("statistics"));
    }

    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        // 声明元组字段
        declarer.declare(new Fields(FieldNames.COMMAND));
    }
}

四 参考
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值