Hbase各種查詢總結


     運用hbase好長時間了,今天利用閑暇時間把Hbase的各種查詢總結下,以后有時間把協處理器和自定義File總結下。

     查詢條件分為:

  1、統計表數據

  2,hbase 簡單分頁

  3,like 查詢

  4 ,  AND 查詢

  5 ,  OR 查詢

  6  ,rowkey 的  in 查詢

  7 , 正則查詢

上代碼先。

package com.query;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.coprocessor.AggregationClient;
import org.apache.hadoop.hbase.client.coprocessor.LongColumnInterpreter;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.FilterList.Operator;
import org.apache.hadoop.hbase.filter.PageFilter;
import org.apache.hadoop.hbase.filter.PrefixFilter;
import org.apache.hadoop.hbase.filter.RegexStringComparator;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.filter.SubstringComparator;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.ValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.log4j.Logger;

import basecommon.PropertyUtil;

public class HbaseConnectionUtils {
	private static Logger log = Logger.getLogger(HbaseConnectionUtils.class);
	private static HbaseConnectionUtils instance = null;
	public static Configuration config = null;
	private static Connection connection = null;

	private HbaseConnectionUtils() {

	}

	/**
	 * @author c_lishaoying 983068303@qq.com
	 * 
	 *         加載集群配置
	 */
	static {
		config = HBaseConfiguration.create();
		config.set("hbase.zookeeper.quorum",
				PropertyUtil.get("zookeeper.quorum"));
		config.set("hbase.zookeeper.property.clientPort",
				PropertyUtil.get("zookeeper.property.clientPort"));
		config.setLong("hbase.client.scanner.timeout.period", Integer.MAX_VALUE);
		try {
			connection = ConnectionFactory.createConnection(config);
		} catch (Exception e) {
			log.debug("connection構建失敗");
		}
	}

	public static HbaseConnectionUtils getInstance() {
		if (instance == null) {
			// 給類加鎖 防止線程並發
			synchronized (HbaseConnectionUtils.class) {
				if (instance == null) {
					instance = new HbaseConnectionUtils();
				}
			}
		}
		return instance;
	}

	public Configuration getConfiguration() {
		return config;
	}

	public Connection getConnection() {
		return connection;
	}

	/**
	 * @author c_lishaoying 983068303@qq.com 獲取表連接
	 * 
	 */
	public static Table getTable(String tableName) {
		try {
			return connection.getTable(TableName.valueOf(tableName));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 協處理器查詢總數據
	 * 
	 */
	public int getRecordCount(String tableName) {
		AggregationClient aggregationClient = new AggregationClient(config);
		Scan scan = new Scan();
		try {
			Long rowCount = aggregationClient.rowCount(
					TableName.valueOf(tableName), new LongColumnInterpreter(),
					scan);
			aggregationClient.close();
			return rowCount.intValue();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return 0;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 協處理器查詢總數據 添加查詢條件的Scan統計總數
	 */
	public static int getTotalRecord(Table keyIndexTable, Configuration config,
			final Scan scan) {
		int count = 0;
		AggregationClient aggregationClient = new AggregationClient(config);
		try {
			Long rowCount = aggregationClient.rowCount(keyIndexTable,
					new LongColumnInterpreter(), scan);
			aggregationClient.close();
			count = rowCount.intValue();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return count;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 協處理器查詢總數據 添加查詢條件的Scan統計總數 queryString數組長度為3
	 *        queryString[0] 列族 queryString[1]字段 queryString[2] 字段值
	 */
	public static int queryByCloumn(String tablename, String[] queryString) {

		int count = 0;
		if (tablename == null) {
			log.info("配置的表名稱為空!");
		} else {
			log.info("表名稱為:" + tablename);
			Table queryTablename = getTable(tablename);
			Scan scan = new Scan();
			scan = getScan(queryString);
			count = getTotalRecord(queryTablename, config, scan);
		}

		return count;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 非協處理器查詢總數據 添加查詢條件的Scan統計總數 queryString數組長度為3
	 *        queryString[0] 列族 queryString[1]字段 queryString[2] 字段值
	 */
	public static int scan(String tablename, String[] condition) {
		Table queryTablename = getTable(tablename);
		String[] s = condition;
		Scan scan = new Scan();
		scan.addColumn(Bytes.toBytes(s[0]), Bytes.toBytes(s[1]));
		SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(
				Bytes.toBytes(s[0]), Bytes.toBytes(s[1]), CompareOp.EQUAL,
				new BinaryComparator(Bytes.toBytes(s[2])));
		scan.setFilter(singleColumnValueFilter);
		int i = 0;
		try {
			ResultScanner rs = queryTablename.getScanner(scan);
			/*
			 * for(Iterator it = rs.iterator(); it.hasNext();){ it.next(); }
			 */
			for (Result r : rs) {
				i++;
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return i;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 查詢字段相等的值 相當於where city = ‘上海’ queryString數組長度為3
	 *        queryString[0] 列族 queryString[1]字段 queryString[2] 字段值
	 */
	public static Scan getScan(String[] condition) {
		Scan scan = new Scan();
		if (condition == null || condition.length != 3) {
			return new Scan();
		}
		FilterList filterList = new FilterList();
		String[] s = condition;
		BinaryComparator comp = new BinaryComparator(Bytes.toBytes(s[2]));
		filterList.addFilter(new SingleColumnValueFilter(Bytes.toBytes(s[0]),
				Bytes.toBytes(s[1]), CompareOp.EQUAL, Bytes.toBytes(s[2])));
		scan.setFilter(filterList);
		return scan;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 查詢字段相等的值 應用正則表達式 相當於where city like ‘%上海%’
	 *        queryString數組長度為3 queryString[0] 列族 queryString[1]字段
	 *        queryString[2] 字段值
	 */
	public static Scan regexscan(String tablename, String[] condition) {
		Table queryTablename = getTable(tablename);
		String[] s = condition;
		Scan scan = new Scan();
		scan.addColumn(Bytes.toBytes(s[0]), Bytes.toBytes(s[1]));
		SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(
				Bytes.toBytes(s[0]), Bytes.toBytes(s[1]), CompareOp.EQUAL,
				new RegexStringComparator(".*" + s[2] + ".*"));
		scan.setFilter(singleColumnValueFilter);
		return scan;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 查詢該列的值
	 */
	public static Scan valuescan(String tablename, String[] condition) {
		Table queryTablename = getTable(tablename);
		String[] s = condition;
		Scan scan = new Scan();

		Filter filter1 = new ValueFilter(CompareOp.EQUAL,
				new SubstringComparator(s[2]));
		scan.setFilter(filter1);
		return scan;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 根據rowkey 查詢 相當於 where id in ()
	 *        queryString數組都為rowkey
	 */
	public static Scan rowscan(String tablename, String[] condition) {
		Scan scan = new Scan();
		FilterList filterList = new FilterList(Operator.MUST_PASS_ONE);
		for (String s : condition) {
			Filter filter = new RowFilter(CompareOp.EQUAL,
					new SubstringComparator(s));
			filterList.addFilter(filter);
		}
		scan.setFilter(filterList);
		return scan;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 查詢該列的值 相當於where city = ‘上海’ AND name =‘酒店’
	 *        queryString數組長度為3 queryString[0] 列族 queryString[1]字段
	 *        queryString[2] 字段值
	 */

	public static Scan listAndColumnscan(String tablename,
			List<String[]> condition) {
		Scan scan = new Scan();
		List<Filter> filters = new ArrayList<Filter>();

		for (String[] s : condition) {
			filters.add(new SingleColumnValueFilter(Bytes.toBytes(s[0]), // 列族
					Bytes.toBytes(s[1]), // 列名
					CompareOp.EQUAL, Bytes.toBytes(s[2]))); // 值
		}
		FilterList filterList = new FilterList(Operator.MUST_PASS_ALL, filters);
		scan.setFilter(filterList);
		return scan;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 查詢該列的值 相當於where city = ‘上海’ OR name =‘酒店’
	 *        queryString數組長度為3 queryString[0] 列族 queryString[1]字段
	 *        queryString[2] 字段值
	 */
	public static Scan listOrColumnscan(String tablename,
			List<String[]> condition) {
		Scan scan = new Scan();
		ArrayList<Filter> listForFilters = new ArrayList<Filter>();
		Filter filter = null;
		for (String[] s : condition) {
			filter = new SingleColumnValueFilter(Bytes.toBytes(s[0]), // 列族
					Bytes.toBytes(s[1]), // 列名
					CompareOp.EQUAL, Bytes.toBytes(s[2]));
			listForFilters.add(filter);
		}
		// 通過將operator參數設置為Operator.MUST_PASS_ONE,達到list中各filter為"或"的關系
		// 默認operator參數的值為Operator.MUST_PASS_ALL,即list中各filter為"並"的關系
		Filter filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE,
				listForFilters);
		scan.setFilter(filterList);// 多條件過濾
		return scan;
	}

	/**
	 * @author c_lishaoying
	 * @email 983068303@qq.com 通過多條件聯合查詢和限制返回頁數 相當於mysql 中的limit 0,1000
	 */
	public Scan queryByFilter(String tablename, List<String[]> arr,
			String starString, String stopString) throws IOException {
		FilterList filterList = new FilterList();
		Scan scan = new Scan();
		for (String[] s : arr) {
			SubstringComparator comp = new SubstringComparator(s[2]);
			filterList
					.addFilter(new SingleColumnValueFilter(Bytes.toBytes(s[0]),
							Bytes.toBytes(s[1]), CompareOp.EQUAL, comp));
		}
		PageFilter pageFilter = new PageFilter(1000);
		filterList.addFilter(pageFilter);
		scan.setFilter(filterList);
		scan.setStartRow(Bytes.toBytes(starString));
		scan.setStartRow(Bytes.toBytes(stopString));
		return scan;
	}

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM