《Spark SQL大数据实例开发》9.2 综合案例实战——电商网站搜索排名统计

《Spark SQL大数据实例开发》9.2 综合案例实战——电商网站搜索排名统计

9.2.1 案例概述
    本节演示一个网站搜索综合案例:以京东为例,用户登录京东网站,在搜索栏中输入搜索词,然后点击搜索按钮,就能在京东网站搜索用户需要的商品。在搜索栏中输入搜索词时,当用户输入第一个词的时候,京东就能根据用户的点击商品搜索排名,自动在搜索栏下拉列表中显示搜索热词,帮助用户快捷的点击需搜索的商品。在网站搜索综合案例中,将实现和京东搜索类似的功能,根据用户搜索词的日志记录,将用户每天搜索排名前3名的商品列出来,系统后台可以将搜索排名记录持久化到数据库中,提供给web系统或其他应用使用。这里将搜索排名前3名记录保存到磁盘文件系统中,以json格式保存。
网站搜索综合案例代码分2个模块:
(1)数据生成模块:模拟数据的生成可以使用爬虫代码程序,从网络上爬取相应的用户搜索数据,进行ETL数据清理。为简化数据爬取和清洗过程,我们采用模拟生成数据的方式,根据综合案例的数据需求,人工生成模拟数据文件,实现同样类似的功能。
(2)网站搜索排名:找出用户每天搜索排名前3名的产品。


数据生成代码: Spark SQLUserlogsHottestDataManually.java

package com.dt.imf;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Random;
import java.util.UUID;

public class Spark SQLUserlogsHottestDataManually {

	public static void main(String[] args) {
		long numberItems = 10000;
			ganerateUserLogs(numberItems, "G:\\Spark SQLData\\");

	}

	/**
	 * 生成userLog
	 * 
	 * @paramnumberItems
	 * @param path
	 */
	private static void ganerateUserLogs(long numberItems, String path) {

		StringBufferuserLogBuffer = new StringBuffer();
			String filename = "Spark SQLUserlogsHot.log";
		// 元数据:Date、UserID、Item、City、Device;

		for (int i = 0; i 


网站搜索排名Spark SQLUserlogsHot代码:  Spark SQLUserlogsHot.java

package com.dt.imf;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.apache.hadoop.hive.ql.parse.HiveParser_IdentifiersParser.function_return;
import org.apache.hadoop.io.IntWritable;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;
import org.apache.spark.broadcast.Broadcast;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;
import org.apache.spark.sql.hive.HiveContext;

import scala.Tuple2;

public class Spark SQLUserlogsHot {

	public static void main(String[] args) {
		SparkConf conf = new SparkConf().setMaster("local").setAppName("Spark SQLUserlogsHottest");
		JavaSparkContext sc = new JavaSparkContext(conf);
		SQLContextsqlContext = new HiveContext(sc);
		JavaRDD lines = sc.textFile("G:\\Spark SQLData\\Spark SQLUserlogsHot.log");
		String device = "iphone";
		final BroadcastdeviceBroadcast = sc.broadcast(device);
	
		JavaRDDlineFilter = lines.filter(new Function() {
			@Override
			public Boolean call(String s) throws Exception {
				return s.contains(deviceBroadcast.value());
			}
		});

		 

		// 组拼字符串(date#Item#userID) 构建KV(date#Item#userID,1)
		JavaPairRDD pairs = lineFilter.mapToPair(new PairFunction() {
			private static final long serialVersionUID = 1L;
			@Override
			public Tuple2 call(String line) throws Exception {
				String[] splitedLine = line.split("\t");
				int one = 1;
				String dataanditemanduserid = splitedLine[0] + "#" + splitedLine[2] + "#"
						+ String.valueOf(splitedLine[1]);
				return new Tuple2(String.valueOf(dataanditemanduserid), Integer.valueOf(one));

			}
		});

	 
		// reducebykey,统计计数

		JavaPairRDDpairsCount = pairs.reduceByKey(new Function2() {

			@Override
			public Integer call(Integer v1, Integer v2) throws Exception {
				return v1 + v2;
			}
		});

		List>pairsCountRows = pairsCount.collect();

		// 动态组拼出JSON
		List userLogsInformations = new ArrayList();

		for (Tuple2 row : pairsCountRows) {
			// 拆分三个字段
			String[] rowSplitedLine = row._1.split("#");
			String rowuserID = rowSplitedLine[2];
			String rowitemID = rowSplitedLine[1];
			String rowdateID = rowSplitedLine[0];

			// 拼接json元数据:Date、UserID、Item、City、Device
			String jsonZip = "{\"Date\":\"" + rowdateID + "\", \"UserID\":\"" + rowuserID + "\", \"Item\":\""
					+ rowitemID + "\", \"count\":" + row._2 + " }";
			userLogsInformations.add(jsonZip);

		}

	 

		// 通过内容为JSON的RDD来构造DataFrame
		JavaRDD userLogsInformationsRDD = sc.parallelize(userLogsInformations);
		DataFrame userLogsInformationsDF = sqlContext.read().json(userLogsInformationsRDD);

		userLogsInformationsDF.show();

		// 注册成为临时表
		userLogsInformationsDF.registerTempTable("userlogsInformations");

		/*
		 * 使用子查询的方式完成目标数据的提取,在目标数据内幕使用窗口函数row_number来进行分组排序: PARTITION BY
		 * :指定窗口函数分组的Key; ORDER BY:分组后进行排序;
		 */

		String sqlText = "SELECT UserID,Item, count " + "FROM (" + "SELECT " + "UserID,Item, count,"
				+ "row_number() OVER (PARTITION BY UserID ORDER BY count DESC) rank" + " FROM userlogsInformations "
				+ ") sub_userlogsInformations " + "WHERE rank <= 3 ";

		System.out.println(sqlText);

		DataFrameuserLogsHotResultDF = sqlContext.sql(sqlText);
		userLogsHotResultDF.show();
		userLogsHotResultDF.write().format("json").save("G://Spark SQLData//Result15.json");
		while (true) {

		}
	}

}


你可能感兴趣的:(Hadoop)