【基于HBase和ElasticSearch构建大数据实时检索项目】

基于HBase和ElasticSearch构建大数据实时检索项目

    • 一、项目说明
    • 二、环境搭建
    • 三、编写程序
    • 四、测试流程

一、项目说明

  1. 利用HBase存储海量数据,解决海量数据存储和实时更新查询的问题;
  2. 利用ElasticSearch作为HBase索引,加快大数据集中实时查询数据;
  3. 使用到的大数据组件有:Hadoop-2.7.3、HBase-1.3.1、zookeeper-3.4.5、ElasticSearch-7.8.0
  4. 实验环境:
    虚拟机(操作系统CentOS7.6) + 个人PC(Windows)+ Eclipse或者Idea
  5. 大数据环境:3节点构成的全分布式环境
  6. 项目系统架构图如下:
    在这里插入图片描述
  7. 本项目是利用hbase和elasticsearch的API来完成数据的写入和检索

二、环境搭建

  1. 创建3台虚拟机,即3节点,主节点内存4G、从节点内存3G,可根据自己电脑配置来设置;
  2. 安装部署Hadoop全分布式,可参考:Hadoop2.7.3全分布式环境搭建
  3. 安装部署zookeeper全分布式,可参考:Zookeeper的集群安装
  4. 安装部署HBase全分布式,可参考:HBase几种安装方式,注意:需要先安装zookeeper并启动后,再安装和启动hbase
  5. 安装部署ElasticSearch集群,可参考:Linux下安装ElasticSearch集群,注意:需要使用es普通用户启动集群,安装成功后各个节点上启动

三、编写程序

本项目是在eclipse上编写

  1. 构建maven工程,配置settings.xml(可配置阿里或华为maven仓库),如下所示:

    <?xml version="1.0" encoding="utf-8"?>  
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"  
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    	xsi:schemaLocation="         http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    	<mirrors>
    		<mirror>  
    			<id>nexus-aliyun</id>  
    			<mirrorOf>central</mirrorOf>  
    			<name>Nexus aliyun</name>  
    			<url>http://maven.aliyun.com/nexus/content/groups/public/</url>  
    		</mirror>  
    		<mirror>  
    			<id>net-cn</id>  
    			<mirrorOf>central</mirrorOf>  
    			<name>Nexus net</name>  
    			<url>http://maven.net.cn/content/groups/public/</url>  
    		</mirror>  
    	</mirrors>  
    	<profiles>  
    		<profile>  
    			<repositories>  
    				<repository>  
    					<id>nexus</id>  
    					<name>local private nexus</name>  
    					<url>http://maven.aliyun.com/nexus/content/groups/public/</url>  
    					<releases>  
    						<enabled>true</enabled>  
    					</releases>  
    					<snapshots>  
    						<enabled>false</enabled>  
    					</snapshots>  
    				</repository>  
    			</repositories>  
    			<pluginRepositories>  
    				<pluginRepository>  
    					<id>nexus</id>  
    					<name>local private nexus</name>  
    					<url>http://maven.aliyun.com/nexus/content/groups/public/</url>  
    					<releases>  
    						<enabled>true</enabled>  
    					</releases>  
    					<snapshots>  
    						<enabled>false</enabled>  
    					</snapshots>  
    				</pluginRepository>  
    			</pluginRepositories>  
    		</profile>  
    	</profiles>  
    	<activeProfiles>  
    		<activeProfile>nexus</activeProfile>  
    	</activeProfiles>  
    </settings>
    
  2. 添加依赖到pom.xml中,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.bigdata</groupId>
        <artifactId>realtimesearch</artifactId>
        <version>1.0-SNAPSHOT</version>
        <!-- Spring boot 父引用 -->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.4.0.RELEASE</version>
        </parent>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
        <!--仓库源-->
        <repositories>
            <repository>
                <id>alimaven</id>
                <name>aliyun maven</name>
                <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
        <dependencies>
            <!-- Spring boot 核心web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- 解决thymeleaf模板引擎对h5页面检查太严格问题 -->
            <dependency>
                <groupId>net.sourceforge.nekohtml</groupId>
                <artifactId>nekohtml</artifactId>
                <version>1.9.22</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <!-- HBase -->
            <dependency>
                <groupId>org.apache.hbase</groupId>
                <artifactId>hbase-client</artifactId>
                <version>1.3.1</version>
                <exclusions>
                    <exclusion>
                        <artifactId>hadoop-mapreduce-client-core</artifactId>
                        <groupId>org.apache.hadoop</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-hdfs</artifactId>
                <version>2.2.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.hbase</groupId>
                <artifactId>hbase-protocol</artifactId>
                <version>1.3.1</version>
            </dependency>
            <!-- ElasticSearch -->
            <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>7.8.0</version>
            </dependency>
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>transport</artifactId>
                <version>7.8.0</version>
            </dependency>
            <!-- 解锁ES运行时没有对应方法的的错误 -->
            <dependency>
                <groupId>org.locationtech.spatial4j</groupId>
                <artifactId>spatial4j</artifactId>
                <version>0.6</version>
            </dependency>
            <!-- zookeeper -->
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.9</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- 解决ES和HBase中 io.netty包冲突 -->
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
                <version>4.1.16.Final</version>
            </dependency>
            <!-- json -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.13</version>
            </dependency>
        </dependencies>
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>jdk.tools</groupId>
                    <artifactId>jdk.tools</artifactId>
                    <version>1.8</version>
                    <scope>system</scope>
                    <systemPath>C:\Program Files\Java\jdk1.8.0_301\lib\tools.jar</systemPath>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <executions>
                        <execution>
                            <phase>compile</phase>
                            <goals>
                                <goal>compile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                </resource>
            </resources>
        </build>
    </project>
    
  3. 新建data目录,并将测试数据放在该目录下,如下图所示:测试数据下载
    在这里插入图片描述

  4. 添加各类配置文件,如conf.propertiesapplication.propertieslog4j.propertieslog4j2.properties等,如下图所示:
    在这里插入图片描述

  5. 配置conf.properties,内容如下:

    	#原始数据路径
    	inputPath =data/
    	#HBase的配置
    	#通过CloudTable服务列表获取的ZK连接地址,运行后可看到日志打印具体内网地址
    	ZKServer=hostname01:2181,hostname02:2181,hostname03:2181
    	#HBase表名
    	tableName=PublicSecurity
    	#HBase列族
    	columnFamily1=Basic
    	columnFamily2=OtherInfo
    	#ElasticSearch的配置,如ES集群名称,虚拟机IP,默认端口
    	clusterName=Es-cluster
    	hostName=192.168.1.109
    	tcpPort=9300
    	indexName=publicsecurity
    	typeName=info
    
  6. 配置application.properties,内容如下:

       server.port=8084
       server.contextPath=/bigdata
       
       #web页面热布署
       spring.thymeleaf.cache=false
       
       #解决html5检查太严格问题
       spring.thymeleaf.mode = LEGACYHTML5
    
  7. 配置log4j.properties,内容如下:

      log4j.rootLogger=INFO,console
      log4j.appender.console=org.apache.log4j.ConsoleAppender
      log4j.appender.console.target=System.out
      log4j.appender.console.layout=org.apache.log4j.PatternLayout
      log4j.appender.console.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
    
  8. 配置log4j2.properties,内容如下:

       name = PropertiesConfig
       property.filename = target/logs
       
       #appenders = console, file
       #配置值是appender的类型,并不是具体appender实例的name
       appenders = rolling
       
       appender.rolling.type = RollingFile
       appender.rolling.name = RollingLogFile
       appender.rolling.fileName=${filename}/automationlogs.log
       appender.rolling.filePattern = ${filename}/automationlogs-%d{MM-dd-yy-HH-mm-ss}-%i.log
       appender.rolling.layout.type = PatternLayout
       appender.rolling.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
       appender.rolling.policies.type = Policies
       appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
       appender.rolling.policies.size.size=100MB
       appender.rolling.strategy.type = DefaultRolloverStrategy
       appender.rolling.strategy.max = 5
        
       rootLogger.level = INFO,console
       rootLogger.appenderRef.rolling.ref = rolling
       rootLogger.appenderRef.rolling.ref = RollingLogFile
    
  9. 编写读取配置文件的工具类ConstantUtil,代码如下:

    	package com.bigdata.utils;
    	import org.apache.log4j.PropertyConfigurator;
    	import org.slf4j.Logger;
    	import org.slf4j.LoggerFactory;
    	import java.io.FileInputStream;
    	import java.io.IOException;
    	import java.util.Properties;
    	/**
    	 * {@docRoot 用于读取配置内容}
    	 * @author suben
    	 */
    	public class ConstantUtil {
    	    public static final Properties PROPS = new Properties();
    	    public static final Logger LOG = LoggerFactory.getLogger(ConstantUtil.class);
    	
    	    public static final String INPUT_PATH;
    	
    	    public static final String ZK_SERVER;
    	    public static final String TABLE_NAME;
    	    public static final String COLUMN_FAMILY_1;
    	    public static final String COLUMN_FAMILY_2;
    	
    	    public static final String INDEX_NAME;
    	    public static final String TYPE_NAME;
    	
    	    //ES集群名,默认值elasticsearch
    	    public static final String CLUSTER_NAME;
    	    //ES集群中某个节点
    	    public static final String HOSTNAME;
    	    //ES连接端口号
    	    public static final int TCP_PORT;
    	
    	
    	    static {
    	
    	        try {
    	            //加载日志配置
    	            PropertyConfigurator.configure(ConstantUtil.class.getClassLoader().getResource("log4j.properties").getPath());
    	            //加载连接配置
    	            PROPS.load(new FileInputStream(ConstantUtil.class.getClassLoader().getResource("conf.properties").getPath()));
    	
    	        } catch (IOException e) {
    	            e.printStackTrace();
    	        }
    	        INPUT_PATH = PROPS.getProperty("inputPath");
    	        ZK_SERVER = PROPS.getProperty("ZKServer");
    	        TABLE_NAME = PROPS.getProperty("tableName");
    	        INDEX_NAME = PROPS.getProperty("indexName").toLowerCase();
    	        TYPE_NAME = PROPS.getProperty("typeName");
    	        COLUMN_FAMILY_1 = PROPS.getProperty("columnFamily1");
    	        COLUMN_FAMILY_2 = PROPS.getProperty("columnFamily2");
    	        CLUSTER_NAME = PROPS.getProperty("clusterName");
    	        HOSTNAME = PROPS.getProperty("hostName");
    	        TCP_PORT = Integer.valueOf(PROPS.getProperty("tcpPort"));
    	
    	    }
    	
    	}
    
    
  10. 编写HBase工具类,代码如下:

    	package com.bigdata.utils;
    
    	import org.apache.hadoop.conf.Configuration;
    	import org.apache.hadoop.hbase.*;
    	import org.apache.hadoop.hbase.client.*;
    	import org.apache.hadoop.hbase.util.Bytes;
    	import org.slf4j.Logger;
    	import java.io.IOException;
    	import java.util.ArrayList;
    	import java.util.HashMap;
    	import java.util.List;
    	import java.util.Map;
    	public class HBaseUtil {
    	
    	    public static Admin admin = null;
    	    public static Configuration conf = null;
    	    public static Connection conn = null;
    	    private HashMap<String, Table> tables = null;
    	    private static final Logger LOG = ConstantUtil.LOG;
    
    	    public HBaseUtil() {
    	        this(ConstantUtil.ZK_SERVER);
    	    }
    	    public HBaseUtil(String zkServer) {
    	        init(zkServer);
    	    }
    	    private void ifNotConnTableJustConn(String tableName) {
    	        if (!tables.containsKey(tableName)) {
    	            this.addTable(tableName);
    	        }
    	    }
    	    public Table getTable(String tableName) {
    	        ifNotConnTableJustConn(tableName);
    	        return tables.get(tableName);
    	    }
    	    public void addTable(String tableName) {
    	        try {
    	            tables.put(tableName, conn.getTable(TableName.valueOf(tableName)));
    	        } catch (IOException e) {
    	            e.printStackTrace();
    	        }
    	    }
    	    public boolean put(String tableName, List<Put> putList) throws Exception {
    	        boolean res = false;
    	        ifNotConnTableJustConn(tableName);
    	        try {
    	            getTable(tableName).put(putList);
    	            res = true;
    	        } catch (IOException e) {
    	            e.printStackTrace();
    	        }
    	        return res;
    	    }
    	    public Result get(String tableName, String row) throws IOException {
    	        Result result = null;
    	        ifNotConnTableJustConn(tableName);
    	        Table newTable = getTable(tableName);
    	        Get get = new Get(Bytes.toBytes(row));
    	        try {
    	            result = newTable.get(get);
    	            KeyValue[] raw = result.raw();
    	        } catch (IOException e) {
    	            e.printStackTrace();
    	        }
    	        return result;
    	    }
    	    public boolean createTable(String tableName, String... columnFamilys) {
    	        boolean result = false;
    	        try {
    	            if (admin.tableExists(TableName.valueOf(tableName))) {
    	                LOG.info(tableName + "表已经存在!");
    	            } else {
    	                HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(tableName));
    	                for (String columnFamily : columnFamilys) {
    	                    tableDesc.addFamily(new HColumnDescriptor(columnFamily.getBytes()));
    	                }
    	
    	                admin.createTable(tableDesc);
    	                result = true;
    	                LOG.info(tableName + "表创建成功!");
    	            }
    	
    	        } catch (IOException e) {
    	            e.printStackTrace();
    	            LOG.info(tableName + "表创建失败 !");
    	        }
    	        return result;
    	    }
    	    public boolean tableExists(String tableName) throws IOException {
    	        return admin.tableExists(TableName.valueOf(tableName));
    	    }
    	    public void disableTable(String tableName) throws IOException {
    	        if (tableExists(tableName)) {
    	            admin.disableTable(TableName.valueOf(tableName));
    	        }
    	
    	    }
    	
    	    /**
    	     * 删除表
    	     *
    	     * @param tableName
    	     */
    	    public void deleteTable(String tableName) throws IOException {
    	        disableTable(tableName);
    	        admin.deleteTable(TableName.valueOf(tableName));
    	    }
    	
    	    /**
    	     * 查询所有表名
    	     *
    	     * @return
    	     * @throws Exception
    	     */
    	    public List<String> getALLTableName() throws Exception {
    	        ArrayList<String> tableNames = new ArrayList<String>();
    	        if (admin != null) {
    	            HTableDescriptor[] listTables = admin.listTables();
    	            if (listTables.length > 0) {
    	                for (HTableDescriptor tableDesc : listTables) {
    	                    tableNames.add(tableDesc.getNameAsString());
    	                }
    	            }
    	        }
    	        return tableNames;
    	    }
    	
    	    /**
    	     * 删除所有表,慎用!仅用于测试环境
    	     */
    	    public void deleteAllTable() throws Exception {
    	        List<String> allTbName = getALLTableName();
    	        for (String s : allTbName) {
    	            LOG.info("Start delete table : " + s + "......");
    	            deleteTable(s);
    	            LOG.info("done delete table : " + s);
    	        }
    	    }
    	
    	    /**
    	     * 初始化配置
    	     *
    	     * @param zkServer
    	     */
    	
    	    public void init(String zkServer) {
    	        tables = new HashMap<String, Table>();
    	        conf = HBaseConfiguration.create();
    	        conf.set("hbase.zookeeper.quorum", zkServer);
    	        
    	        try {
    	            conn = ConnectionFactory.createConnection(conf);
    	            admin = conn.getAdmin();
    	        } catch (IOException e) {
    	            e.printStackTrace();
    	        }
    	    }
    	
    	    /**
    	     * 清理所有连接
    	     *
    	     * @throws IOException
    	     */
    	    public void clear() throws IOException {
    	        for (Map.Entry<String, Table> m : tables.entrySet()) {
    	            m.getValue().close();
    	        }
    	        admin.close();
    	        conn.close();
    	        conf.clear();
    	    }
    	
    	    /**
    	     * 关卡登记信息bayonet:姓名,身份证号,年龄,性别,关卡号,日期时间,通关形式
    	     * 住宿登记信息hotel:姓名,身份证号,年龄,性别,起始日期,结束日期,同行人
    	     * 网吧登记信息internet:姓名,身份证号,年龄,性别,网吧名,日期,逗留时长
    	     */
    	    //用于提前建好表和列族
    	    public static void preDeal() throws Exception {
    	        HBaseUtil hBaseUtils = new HBaseUtil();
    	        hBaseUtils.createTable(ConstantUtil.TABLE_NAME, ConstantUtil.COLUMN_FAMILY_1, ConstantUtil.COLUMN_FAMILY_2);
    	
    	    }
    	
    	    //测试
    	    public static void test() throws Exception {
    	        HBaseUtil hBaseUtils = new HBaseUtil();
    	        long startTime = System.currentTimeMillis();
    	        String tb = "testTb";
    	        String colFamily = "info";
    	        String col = "name";
    	        String row = "100000";
    	        String value = "张三";
    	        hBaseUtils.createTable(tb, colFamily);
    	        List<Put> listPut = new ArrayList<>();
    	        Put put = new Put(Bytes.toBytes(row));
    	        put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col), Bytes.toBytes(value));
    	        listPut.add(put);
    	        hBaseUtils.put(tb, listPut);
    	        Result res = hBaseUtils.get("testTb", "100000");
    	        List<Cell> list = res.getColumnCells(Bytes.toBytes("info"), Bytes.toBytes("name"));
    	        for (Cell c : list) {
    	            LOG.info(Bytes.toString(CellUtil.cloneFamily(c)));
    	            LOG.info(Bytes.toString(CellUtil.cloneQualifier(c)));
    	            LOG.info(Bytes.toString(CellUtil.cloneValue(c)));
    	        }
    	
    	        long endTime = System.currentTimeMillis();
    	        float seconds = (endTime - startTime) / 1000F;
    	        LOG.info("  耗时" + Float.toString(seconds) + " seconds.");
    	    }
    	    public static void main(String[] args) throws Exception {
    	        test();
    	        preDeal();
    	    }
    	
    	}
    
    
  11. 编写ElasticSearch工具类,代码如下:

    			package com.bigdata.utils;
    			import com.alibaba.fastjson.JSONObject;
    			import org.apache.lucene.search.TotalHits;
    			import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
    			//import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
    			import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
    			import org.elasticsearch.action.index.IndexRequestBuilder;
    			import org.elasticsearch.action.index.IndexResponse;
    			import org.elasticsearch.action.search.SearchRequestBuilder;
    			import org.elasticsearch.action.search.SearchResponse;
    			import org.elasticsearch.action.support.master.AcknowledgedResponse;
    			import org.elasticsearch.client.IndicesAdminClient;
    			import org.elasticsearch.client.transport.TransportClient;
    			import org.elasticsearch.common.settings.Settings;
    			import org.elasticsearch.common.transport.TransportAddress;
    			import org.elasticsearch.common.xcontent.XContentBuilder;
    			import org.elasticsearch.common.xcontent.XContentType;
    			import org.elasticsearch.index.query.QueryBuilder;
    			import org.elasticsearch.index.query.QueryBuilders;
    			import org.elasticsearch.search.SearchHit;
    			import org.elasticsearch.search.SearchHits;
    			import org.elasticsearch.transport.client.PreBuiltTransportClient;
    			import org.slf4j.Logger;
    			
    			import java.io.IOException;
    			import java.net.InetAddress;
    			import java.net.UnknownHostException;
    			import java.util.ArrayList;
    			import java.util.List;
    			import java.util.Map;
    			import java.util.Set;
    			
    			import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
    			
    			public class ElasticSearchUtil {
    			
    			    //构建Settings对象
    			    private static Settings settings = Settings.builder().put("cluster.name", ConstantUtil.CLUSTER_NAME)
    			            .put("client.transport.sniff", false).build();
    			    //TransportClient对象,用于连接ES集群
    			    private volatile TransportClient client;
    			    private final static Logger LOG = ConstantUtil.LOG;
    			
    			    public ElasticSearchUtil() {
    			        init();
    			    }
    			
    			    /**
    			     * 同步synchronized(*.class)代码块的作用和synchronized static方法作用一样,
    			     * 对当前对应的*.class进行持锁,static方法和.class一样都是锁的该类本身,同一个监听器
    			     *
    			     * @return
    			     * @throws UnknownHostException
    			     */
    			    public TransportClient getClient() {
    			        if (client == null) {
    			            synchronized (TransportClient.class) {
    			                try {
    			                    client = new PreBuiltTransportClient(settings)
    			                            .addTransportAddress(new TransportAddress(InetAddress.getByName(ConstantUtil.HOSTNAME), ConstantUtil.TCP_PORT));
    			                } catch (UnknownHostException e) {
    			                    e.printStackTrace();
    			                }
    			            }
    			        }
    			        return client;
    			    }
    			
    			    /**
    			     * 获取索引管理的IndicesAdminClient
    			     */
    			    public IndicesAdminClient getAdminClient() {
    			        return getClient().admin().indices();
    			    }
    			
    			    /**
    			     * 判定索引是否存在
    			     *
    			     * @param indexName
    			     * @return
    			     */
    			    public boolean isExistsIndex(String indexName) {
    			        IndicesExistsResponse response = getAdminClient().prepareExists(indexName).get();
    			        return response.isExists() ? true : false;
    			    }
    			
    			    /**
    			     * 创建索引
    			     *
    			     * @param indexName
    			     * @return
    			     */
    			    public boolean createIndex(String indexName) {
    			        CreateIndexResponse createIndexResponse = getAdminClient()
    			                .prepareCreate(indexName.toLowerCase())
    			                .get();
    			        return createIndexResponse.isAcknowledged() ? true : false;
    			    }
    			
    			
    			    /**
    			     * 删除索引
    			     *
    			     * @param indexName
    			     * @return
    			     */
    			    public boolean deleteIndex(String indexName) {
    			        AcknowledgedResponse deleteResponse = getAdminClient()
    			                .prepareDelete(indexName.toLowerCase())
    			                .execute()
    			                .actionGet();
    			        return deleteResponse.isAcknowledged() ? true : false;
    			    }
    			
    			    /**
    			     * 为索引indexName设置mapping
    			     *
    			     * @param indexName
    			     * @param typeName
    			     * @param mapping
    			     */
    			    public void setMapping(String indexName, String typeName, String mapping) {
    			        getAdminClient().preparePutMapping(indexName)
    			                .setType(typeName)
    			                .setSource(mapping, XContentType.JSON)
    			                .get();
    			    }
    			
    			    /**
    			     * 创建文档,相当于往表里面insert一行数据
    			     *
    			     * @param indexName
    			     * @param typeName
    			     * @param id
    			     * @param document
    			     * @return
    			     * @throws IOException
    			     */
    			    public long addDocument(String indexName, String typeName, String id, Map<String, Object> document) throws IOException {
    			        Set<Map.Entry<String, Object>> documentSet = document.entrySet();
    			        IndexRequestBuilder builder = getClient().prepareIndex(indexName, typeName, id);
    			        XContentBuilder xContentBuilder = jsonBuilder().startObject();
    			        for (Map.Entry e : documentSet) {
    			            xContentBuilder = xContentBuilder.field(e.getKey().toString(), e.getValue());
    			        }
    			        IndexResponse response = builder.setSource(xContentBuilder.endObject()).get();
    			        return response.getVersion();
    			    }
    			
    			
    			    public List<Map<String, Object>> queryStringQuery(String text) {
    			        List<Map<String, Object>> resListMap = null;
    			        QueryBuilder match = QueryBuilders.queryStringQuery(text);
    			        SearchRequestBuilder search = getClient().prepareSearch()
    			                .setQuery(match); //分页 可选
    			        //搜索返回搜索结果
    			        SearchResponse response = search.get();
    			        //命中的文档
    			        SearchHits hits = response.getHits();
    			        //命中总数
    			        TotalHits total = hits.getTotalHits();
    			        SearchHit[] hitAarr = hits.getHits();
    			        //循环查看命中值
    			        resListMap = new ArrayList<Map<String, Object>>();
    			        for (SearchHit hit : hitAarr) {
    			            //文档元数据
    			            String index = hit.getIndex();
    			            //文档的_source的值
    			            Map<String, Object> resultMap = hit.getSourceAsMap();
    			            resListMap.add(resultMap);
    			
    			        }
    			        return resListMap;
    			
    			    }
    			
    			    private void init() {
    			        try {
    			            client = new PreBuiltTransportClient(settings)
    			                    .addTransportAddress(new TransportAddress(InetAddress.getByName(ConstantUtil.HOSTNAME), ConstantUtil.TCP_PORT));
    			        } catch (UnknownHostException e) {
    			            e.printStackTrace();
    			        }
    			    }
    			
    			
    			    //用于提前建好索引,相当于关系型数据库当中的数据库
    			    public static void preDealCreatIndex() {
    			        ElasticSearchUtil esUtils = new ElasticSearchUtil();
    			        LOG.info("start create index..............");
    			        esUtils.createIndex(ConstantUtil.INDEX_NAME);
    			        LOG.info("finished create index !");
    			    }
    			
    			    /**
    			     * 关卡登记信息bayonet:姓名,身份证号,年龄,性别,关卡号,日期时间,通关形式
    			     * 住宿登记信息hotel:姓名,身份证号,年龄,性别,起始日期,结束日期,同行人
    			     * 网吧登记信息internet:姓名,身份证号,年龄,性别,网吧名,日期,逗留时长
    			     * name,id,age,gender,
    			     * hotelAddr,hotelInTime,hotelOutTime,acquaintancer,
    			     * barAddr,internetDate,timeSpent,
    			     * bayonetAddr,crossDate,tripType
    			     */
    			    public static void preDealSetMapping() {
    			
    			        JSONObject mappingTypeJson = new JSONObject();
    			        JSONObject propertiesJson = new JSONObject();
    			
    			        JSONObject idJson = new JSONObject();
    			        idJson.put("type", "keyword");
    			        idJson.put("store", "true");
    			        propertiesJson.put("id", idJson);
    			
    			        JSONObject nameJson = new JSONObject();
    			        nameJson.put("type", "keyword");
    			        propertiesJson.put("name", nameJson);
    			
    			        JSONObject uidJson = new JSONObject();
    			        uidJson.put("type", "keyword");
    			        uidJson.put("store", "false");
    			        propertiesJson.put("uid", uidJson);
    			
    			
    			        JSONObject hotelAddr = new JSONObject();
    			        hotelAddr.put("type", "text");
    			        propertiesJson.put("address", hotelAddr);
    			
    			        JSONObject happenedDate = new JSONObject();
    			        happenedDate.put("type", "date");
    			        happenedDate.put("format", "yyyy-MM-dd");
    			        propertiesJson.put("happenedDate", happenedDate);
    			
    			        JSONObject endDate = new JSONObject();
    			        endDate.put("type", "date");
    			        endDate.put("format", "yyyy-MM-dd");
    			        propertiesJson.put("endDate", endDate);
    			
    			        JSONObject acquaintancer = new JSONObject();
    			        acquaintancer.put("type", "keyword");
    			        propertiesJson.put("acquaintancer", acquaintancer);
    			
    			
    			        mappingTypeJson.put("properties", propertiesJson);
    			
    			        LOG.info("start set mapping to " + ConstantUtil.INDEX_NAME + " " + ConstantUtil.TYPE_NAME + " .....");
    			        LOG.info(mappingTypeJson.toString());
    			        ElasticSearchUtil esUtils = new ElasticSearchUtil();
    			        esUtils.setMapping(ConstantUtil.INDEX_NAME, ConstantUtil.TYPE_NAME, mappingTypeJson.toString());
    			        LOG.info("set mapping done!!!");
    			    }
    			
    			    //用于测试
    			    public static void test() {
    			        String index = "esindex";
    			        System.out.println("createIndex..............");
    			        ElasticSearchUtil esUtils = new ElasticSearchUtil();
    			        esUtils.createIndex(index);
    			        System.out.println("createIndex done!!!!!!!!!!!");
    			        System.out.println("isExists = " + esUtils.isExistsIndex(index));
    			        System.out.println("deleteIndex...............");
    			        esUtils.deleteIndex(index);
    			        System.out.println("deleteIndex done!!!!");
    			    }
    			
    			    public static void main(String[] args) throws IOException {
    			        preDealCreatIndex();
    			        preDealSetMapping();
    			        test();
    			    }
    			}
    
  12. 编写数据写入HBase和ES的实现类,代码如下:

    		package com.bigdata.insert;
    		
    		import org.apache.hadoop.hbase.client.Put;
    		import org.apache.hadoop.hbase.util.Bytes;
    		
    		import com.bigdata.utils.ConstantUtil;
    		import com.bigdata.utils.ElasticSearchUtil;
    		import com.bigdata.utils.HBaseUtil;
    		
    		import java.io.BufferedReader;
    		import java.io.File;
    		import java.io.FileReader;
    		import java.util.*;
    		
    		/**
    		 * 读取本地文件并解析数据,之后插入HBase、ElasticSearch
    		 */
    		public class LoadDataToHBaseAndES {
    		
    		    private HBaseUtil hBaseUtil;
    		    private ElasticSearchUtil elasticSearchUtil;
    		
    		
    		    public LoadDataToHBaseAndES() {
    		    }
    		
    		
    		    /**
    			     * 关卡登记信息bayonet:姓名,身份证号,年龄,性别,关卡号,日期时间,通关形式
    			     * 住宿登记信息hotel:姓名,身份证号,年龄,性别,起始日期,结束日期,同行人
    			     * 网吧登记信息internet:姓名,身份证号,年龄,性别,网吧名,日期,逗留时长
    		     * name,uid,age,gender,
    		     * hotelAddr,happenedDate,endDate,acquaintancer,
    		     * barAddr,happenedDate,duration,
    		     * bayonetAddr,happenedDate,tripType
    		     */
    		    public void insert() throws Exception {
    		        hBaseUtil = new HBaseUtil();
    		        elasticSearchUtil = new ElasticSearchUtil();
    		        String filePath = ConstantUtil.INPUT_PATH;
    		
    		        File dir = new File(filePath);
    		        File[] files = dir.listFiles();
    		        if (files != null) {
    		            for (File file : files) {
    		                if (file.isDirectory()) {
    		                    System.out.println(file.getName() + "This is a directory!");
    		                } else {
    		                    //住宿登记信息
    		                    if (file.getName().contains("hotel")) {
    		                        BufferedReader reader = null;
    		                        reader = new BufferedReader(new FileReader(filePath + file.getName()));
    		                        String tempString = null;
    		                        while ((tempString = reader.readLine()) != null) {
    		                            //Blank line judgment
    		                            if (!tempString.isEmpty()) {
    		                                List<Put> putList = new ArrayList<Put>();
    		                                String[] elements = tempString.split(",");
    		                                //生成不重复用户ID,
    		                                String id = UUID.randomUUID().toString();
    		                                Put put = new Put(Bytes.toBytes(id));
    		                                //将数据添加至hbase库
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("name"), Bytes.toBytes(elements[0]));
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("uid"), Bytes.toBytes(elements[1]));
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("age"), Bytes.toBytes(elements[2]));
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("gender"), Bytes.toBytes(elements[3]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("event"), Bytes.toBytes("hotel"));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("address"), Bytes.toBytes(elements[4]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("happenedDate"), Bytes.toBytes(elements[5]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("endDate"), Bytes.toBytes(elements[6]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("acquaintancer"), Bytes.toBytes(elements[7]));
    		                                putList.add(put);
    		                                ConstantUtil.LOG.info("hotel_info start putting to HBase ....:" + id + " " + tempString);
    		                                hBaseUtil.put(ConstantUtil.TABLE_NAME, putList);
    		                                //将数据添加至ES库
    		                                Map<String, Object> esMap = new HashMap<String, Object>();
    		                                esMap.put("id", id);
    		                                esMap.put("name", elements[0]);
    		                                esMap.put("uid", elements[1]);
    		                                esMap.put("address", elements[4]);
    		                                esMap.put("happenedDate", elements[5]);
    		                                esMap.put("endDate", elements[6]);
    		                                esMap.put("acquaintancer", elements[7]);
    		                                elasticSearchUtil.addDocument(ConstantUtil.INDEX_NAME, ConstantUtil.TYPE_NAME, id, esMap);
    		                                ConstantUtil.LOG.info("start add document to ES..." + ConstantUtil.INDEX_NAME + " " + ConstantUtil.TYPE_NAME + " " + id + " " + esMap);
    		                            }
    		                        }
    		
    		                        reader.close();
    		                    }
    		                    //网吧登记信息
    		                    else if (file.getName().contains("internet")) {
    		                        BufferedReader reader = null;
    		                        reader = new BufferedReader(new FileReader(filePath + file.getName()));
    		                        String tempString = null;
    		                        while ((tempString = reader.readLine()) != null) {
    		                            //Blank line judgment
    		                            if (!tempString.isEmpty()) {
    		                                List<Put> putList = new ArrayList<Put>();
    		                                String[] elements = tempString.split(",");
    		                                //生成不重复用户ID,
    		                                String id = UUID.randomUUID().toString();
    		                                Put put = new Put(Bytes.toBytes(id));
    		                                //将数据添加至hbase库
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("name"), Bytes.toBytes(elements[0]));
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("uid"), Bytes.toBytes(elements[1]));
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("age"), Bytes.toBytes(elements[2]));
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("gender"), Bytes.toBytes(elements[3]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("event"), Bytes.toBytes("internetBar"));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("address"), Bytes.toBytes(elements[4]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("happenedDate"), Bytes.toBytes(elements[5]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("duration"), Bytes.toBytes(elements[6]));
    		                                putList.add(put);
    		                                ConstantUtil.LOG.info("internet_info start putting to HBase ... :" + id + " " + tempString);
    		                                hBaseUtil.put(ConstantUtil.TABLE_NAME, putList);
    		                                //将数据添加至ES库
    		                                Map<String, Object> esMap = new HashMap<String, Object>();
    		                                esMap.put("id", id);
    		                                esMap.put("name", elements[0]);
    		                                esMap.put("uid", elements[1]);
    		                                esMap.put("address", elements[4]);
    		                                esMap.put("happenedDate", elements[5]);
    		                                elasticSearchUtil.addDocument(ConstantUtil.INDEX_NAME, ConstantUtil.TYPE_NAME, id, esMap);
    		                                ConstantUtil.LOG.info("start add document to ES..." + ConstantUtil.INDEX_NAME + " " + ConstantUtil.TYPE_NAME + " " + id + " " + esMap);
    		                            }
    		                        }
    		                        reader.close();
    		
    		                    }
    		                    //关卡登记信息
    		                    else if (file.getName().contains("bayonet")) {
    		                        BufferedReader reader = null;
    		                        reader = new BufferedReader(new FileReader(filePath + file.getName()));
    		                        String tempString = null;
    		                        while ((tempString = reader.readLine()) != null) {
    		                            //Blank line judgment
    		                            if (!tempString.isEmpty()) {
    		                                List<Put> putList = new ArrayList<Put>();
    		                                String[] elements = tempString.split(",");
    		                                //生成不重复用户ID,
    		                                String id = UUID.randomUUID().toString();
    		                                Put put = new Put(Bytes.toBytes(id));
    		                                //将数据添加至hbase库
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("name"), Bytes.toBytes(elements[0]));
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("uid"), Bytes.toBytes(elements[1]));
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("age"), Bytes.toBytes(elements[2]));
    		                                put.addColumn(Bytes.toBytes("Basic"), Bytes.toBytes("gender"), Bytes.toBytes(elements[3]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("event"), Bytes.toBytes("bayonet"));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("address"), Bytes.toBytes(elements[4]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("happenedDate"), Bytes.toBytes(elements[5]));
    		                                put.addColumn(Bytes.toBytes("OtherInfo"), Bytes.toBytes("tripType"), Bytes.toBytes(elements[6]));
    		                                putList.add(put);
    		                                hBaseUtil.put(ConstantUtil.TABLE_NAME, putList);
    		                                ConstantUtil.LOG.info("bayonet_info start putting to HBase....:" + id + " " + tempString);
    		                                //将数据添加至ES库
    		                                Map<String, Object> esMap = new HashMap<String, Object>();
    		                                esMap.put("id", id);
    		                                esMap.put("name", elements[0]);
    		                                esMap.put("uid", elements[1]);
    		                                esMap.put("address", elements[4]);
    		                                esMap.put("happenedDate", elements[5]);
    		                                elasticSearchUtil.addDocument(ConstantUtil.INDEX_NAME, ConstantUtil.TYPE_NAME, id, esMap);
    		                                ConstantUtil.LOG.info("start add document to ES..." + ConstantUtil.INDEX_NAME + " " + ConstantUtil.TYPE_NAME + " " + id + " " + esMap);
    		                            }
    		                        }
    		                        reader.close();
    		                    }
    		                    //数据描述文件跳过
    		                    else {
    		                        continue;
    		                    }
    		                }
    		            }
    		            ConstantUtil.LOG.info("load and insert done !!!!!!!!!!!!!!!!!!");
    		        }
    		
    		    }
    		
    		    public static void start() throws Exception {
    		        LoadDataToHBaseAndES load2DB = new LoadDataToHBaseAndES();
    		        load2DB.insert();
    		    }
    		
    		
    		    public static void main(String[] args) throws Exception {
    		        start();
    		    }
    		}
    
  13. 编写Query查询类,代码如下:

       package com.bigdata.query;
    
       import com.alibaba.fastjson.JSONObject;
       import com.bigdata.utils.ConstantUtil;
       import com.bigdata.utils.ElasticSearchUtil;
       import com.bigdata.utils.HBaseUtil;
       
       import org.apache.hadoop.hbase.Cell;
       import org.apache.hadoop.hbase.CellUtil;
       import org.apache.hadoop.hbase.client.Result;
       import org.apache.hadoop.hbase.util.Bytes;
       
       import java.io.IOException;
       import java.util.List;
       import java.util.Map;
       
       /**
        *
        * 搜索逻辑是先搜索ElasticSearch,再查HBase
        */
       public class Query {
           private HBaseUtil hBaseUtil = new HBaseUtil();
           private ElasticSearchUtil elasticSearchUtil = new ElasticSearchUtil();
           private JSONObject result = new JSONObject();
           private JSONObject tmpJS = new JSONObject();
       
           public String query(String target) {
               result.clear();
               tmpJS.clear();
       
               long startTime = System.currentTimeMillis();
               List<Map<String, Object>> listMap = elasticSearchUtil.queryStringQuery(target);
               long endTime = System.currentTimeMillis();
               float seconds = (endTime - startTime) / 1000F;
               ConstantUtil.LOG.info("ElasticSearch查询耗时" + Float.toString(seconds) + " seconds.");
               for (Map<String, Object> m : listMap) {
                   String id = m.get("id").toString();
                   JSONObject tmpJS = new JSONObject();
                   tmpJS.put("id", id);
                   Result res = null;
                   try {
                       long s1 = System.currentTimeMillis();
                       res = hBaseUtil.get(ConstantUtil.TABLE_NAME, id);
                       long e1 = System.currentTimeMillis();
                       float se1 = (e1 - s1) / 1000F;
                       ConstantUtil.LOG.info("HBase查询耗时" + Float.toString(se1) + " seconds.");
                       Cell[] cells = res.rawCells();
                       for (Cell cell : cells) {
                           String col = Bytes.toString(CellUtil.cloneQualifier(cell));
                           System.out.println(col);
                           String value = Bytes.toString(CellUtil.cloneValue(cell));
                           System.out.println(value);
                           tmpJS.put(col, value);
                       }
                       result.put(id, tmpJS);
                   } catch (IOException e) {
                       e.printStackTrace();
                       result.put(id, "查询失败!");
                   }
               }
               return result.toString();
           }
       
           public static void main(String[] args) throws Exception {
               Query query = new Query();
               long startTime = System.currentTimeMillis();
               System.out.println(query.query("100004"));
               long endTime = System.currentTimeMillis();
               float seconds = (endTime - startTime) / 1000F;
               ConstantUtil.LOG.info("  耗时" + Float.toString(seconds) + " seconds.");
           }
       }
    
    
  14. 编写ManagerQuery查询类,代码如下:

       package com.bigdata.manager;
    
       import org.springframework.stereotype.Component;
       
       import com.bigdata.query.Query;
       
       @Component
       public class ManagerQuery {
           private static Query query = new Query();
       
       
           public static String getQueryResult(String target) {
               try {
                   String result =  query.query(target);
                   System.out.println(result);
                   return result;
               } catch (Exception e) {
                   e.printStackTrace();
                   return "查询出现异常,请通知研发人员!";
               }
           }
       
           public static void main(String[] args) {
               String target = "牧之桃";
               String result = ManagerQuery.getQueryResult(target);
               System.out.println(result);
           }
       }
    
  15. 编写SearchService服务类(可参考SpringMVC代码写作),代码如下:

       package com.bigdata.service;
    
       import org.springframework.boot.SpringApplication;
       import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
       import org.springframework.context.annotation.ComponentScan;
       import org.springframework.web.bind.annotation.RequestMapping;
       import org.springframework.web.bind.annotation.RestController;
       import com.bigdata.manager.ManagerQuery;
       
       @RestController
       @EnableAutoConfiguration
       @ComponentScan(basePackages = {"com.bigdata"})
       public class SearchService {
       	
           @RequestMapping("/search")
           public String search(String target) {
               try {
                   return ManagerQuery.getQueryResult(target);
               } catch (Exception e) {
                   e.printStackTrace();
               }
               return "不小心出错了!";
           }
       
           // 主方法,像一般的Java类一般去右击run as application时候,执行该方法
           public static void main(String[] args) throws Exception {
               SpringApplication.run(SearchService.class, args);
           }
       }
    
    
  16. 编写SearchController控制类(可参考SpringMVC代码写作),代码如下:

       package com.bigdata.controller;
    
       import org.springframework.boot.SpringApplication;
       import org.springframework.stereotype.Controller;
       import org.springframework.ui.ModelMap;
       import org.springframework.web.bind.annotation.RequestMapping;
       
       /**
        * 注解声明,该类为Controller类 并自动加载所需要的其它类
        */
       @Controller
       public class SearchController {
           @RequestMapping("/index")
           String testdo(ModelMap map) {
               //这里返回HTML页面
               return "index_search";
           }
       
           // 主方法,像一般的Java类一般去右击run as application时候,执行该方法
           public static void main(String[] args) {
               SpringApplication.run(SearchController.class, args);
           }
       
       }
    
    
  17. 编写ApplicationBootSystem启动类,代码如下:

    package com.bigdata.boot;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * 根启动类
     */
    @SpringBootApplication
    @ComponentScan(basePackages = "com.bigdata")
    public class ApplicationBootSystem {
        public static void main(String[] args) {
            SpringApplication.run(ApplicationBootSystem.class, args);
        }
    }
    
  18. 新建static并在其下新建plugins,并将bootstrap-3.3.7和bootstrap-table包复制到该目录下
    在这里插入图片描述

  19. 新建template目录,并在其下面新建index_search.html文件
    在这里插入图片描述
    具体代码如下:

     	<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
        <title>Realtime Search</title>
        <!-- Bootstrap -->
        <link href="plugins/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet">
        <link href="plugins/bootstrap-table/bootstrap-table.min.css" rel="stylesheet">
        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>;
        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>;
        <![endif]-->
    </head>
    <body>
    <div class="container">
        <div class="row">
            <!-- onsubmit设置成return false,不再显式提交form -->
            <div class="col-md-8 col-md-offset-2 text-center"
                 onsubmit="return false">
                <form class="form-inline">
                    <div class="form-group">
                        <label for="target">请输入条件</label> <input type="text"
                                                                 class="form-control" id="target" name="target" placeholder="请输入条件">
                    </div>
                    <button type="submit" id="submit" class="btn btn-primary">搜一下</button>
                </form>
            </div>
        </div>
        <!-- 在下一行中,添加一个bs系统自带的表格 -->
        <div class="row">
            <table id="table"></table>
        </div>
    </div>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="http://code.jquery.com/jquery-1.12.1.min.js" ;></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="plugins/bootstrap-3.3.7/js/bootstrap.min.js"></script>
    <!-- 加入bootstrap table依赖 -->
    <script src="plugins/bootstrap-table/bootstrap-table.min.js"></script>
    <script src="plugins/bootstrap-table/bootstrap-table-locale-all.min.js"></script>
    <script type="text/javascript">
        $(function () {
            <!--初始化表格的样式 -->
            $('#table').bootstrapTable({
                columns: [{
                    field: 'id',
                    title: '记录id',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                },{
                    field: 'name',
                    title: '姓名',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                }, {
                    field: 'uid',
                    title: '用户id',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                }, {
                    field: 'age',
                    title: '年龄',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                }, {
                    field: 'gender',
                    title: '性别',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                }, {
                    field: 'event',
                    title: '事件',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                },{
                    field: 'address',
                    title: '地址',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                }, {
                    field: 'happenedDate',
                    title: '发生时间',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                }, {
                    field: 'acquaintancer',
                    title: '同行人',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                },{
                    field: 'endDate',
                    title: '结束时间',
                    formatter: function (value, row, index) {
                        var a = "";
                        if (value == $("#target").val()) {
                            a = '<span style="color:#5858FA">' + value + '</span>';
                        } else {
                            a = '<span style="color#190707">' + value + '</span>';
                        }
                        return a;
                    }
                }]
            });
            //为submit按钮绑定click事件,填充点击查询后的数据查询
            $("#submit").click(function () {
                $.ajax({
                    url: '/bigdata/search',
                    data: "target=" + $("#target").val(),
                    cache: false,//false是不缓存,true为缓存
                    async: true,//true为异步,false为同步
                    beforeSend: function () {
                        //请求前
                    },
                    success: function (result) {
                        try {
                            var resultArray = new Array();
                            js = JSON.parse(result);
                            for (var p in js) {
                                resultArray.push(js[p])
                                console.log(js[p]);
                            }
                            console.log(resultArray);
                            $("#table").bootstrapTable('load', resultArray);
    
                        } catch (e) {
                            window.alert(result);
                            $("#table").bootstrapTable('load', [{
                                "result": "什么也没有找到"
                            }]);
                        }
                    },
                    complete: function () {
                        //请求结束时
                    },
                    error: function () {
                        //请求失败时
                    }
                })
            });
        });
    
    </script>
    </body>
    </html>
    
  20. 写完成后,项目结构如下所示
    在这里插入图片描述

四、测试流程

  1. 先执行HBaseUtil工具类main方法,完成HBase测试表和目标表的创建,验证程序和hbase的连通性;

  2. 再执行ElasticSearch工具类main方法,完成ElasticSearch测试表和目标表的创建,验证程序和ElasticSearch的连通性;

  3. 再执行LoadDataToHBaseAndES类,完成数据写入HBase和ElasticSearch中;

  4. 再执行ApplicationBootSystem启动类,启动springboot入口程序;

  5. 最后打开浏览器输入:http://localhost:8084/bigdata/index,在打开的界面中的搜索框输入查询关键字,如输入3,点击【搜一下】按钮,正常情况下会看到如下结果:
    在这里插入图片描述

  6. 尝试输入不同的条件,查看到不同的结果,注意: 需要观察检索的实时性或者速度是很快的。另外,还可以尝试下修改测试数据集,使得其数据量变得更大些,然后再查看其检索速度,读者可以自行尝试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/58995.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

⌈C++⌋从无到有了解并掌握C++面向对象三大特性——封装、继承、多态

前置知识&#xff1a;类和对象 参考书籍&#xff1a;《C Primer 第五版》 目录 什么是面向过程&#xff1f;什么是面向对象&#xff1f; 一、封装 1、封装的含义以及如何实现封装 1.1 访问限定符&#xff08;访问说明符&#xff09; 1.2 什么是封装&#xff1f; 2、封装的优点…

css word-break

上面的一行还是可以放置很多个字符的&#xff0c;但是就是换行了。 要求填充满整行&#xff0c;超过在换行 加上word-break:break-all;就行

uniapp返回

// 监听返回事件onNavigationBarButtonTap() {uni.showModal({title: 提示,content: 确定要返回吗&#xff1f;,success: (res) > {if (res.confirm) {uni.navigateBack({delta: 2})}}})},

牛客网Verilog刷题——VL46

牛客网Verilog刷题——VL46 题目解析答案 题目 根据题目提供的双口RAM代码和接口描述&#xff0c;实现同步FIFO&#xff0c;要求FIFO位宽和深度参数化可配置。电路的接口如下图所示。   双口RAM端口说明&#xff1a; 同步FIFO端口说明&#xff1a; 双口RAM代码如下&#xff…

【LangChain】向量存储(Vector stores)

LangChain学习文档 【LangChain】向量存储(Vector stores)【LangChain】向量存储之FAISS 概要 存储和搜索非结构化数据的最常见方法之一是嵌入它并存储生成的嵌入向量&#xff0c;然后在查询时嵌入非结构化查询并检索与嵌入查询“最相似”的嵌入向量。向量存储负责存储嵌入数…

【Jmeter】配置不同业务请求比例,应对综合场景压测

目录 前言 Jmeter5.0新特性 核心改进 其他变化 资料获取方法 前言 Jmeter 5.0这次的核心改进是在许多地方改进了对 Rest 的支持&#xff0c;此外还有调试功能、录制功能的增强、报告的改进等。 我也是因为迁移到了Mac&#xff0c;准备在Mac上安装Jmeter的时候发现它已经…

机器学习---概述(一)

文章目录 1.人工智能、机器学习、深度学习2.机器学习的工作流程2.1 获取数据集2.2 数据基本处理2.3 特征工程2.3.1 特征提取2.3.2 特征预处理2.3.3 特征降维 2.4 机器学习2.5 模型评估 3.机器学习的算法分类3.1 监督学习3.1.1 回归问题3.1.2 分类问题 3.2 无监督学习3.3 半监督…

Scikit Learn识别手写数字 -- 机器学习项目基础篇(6)

Scikit learn是机器学习社区中使用最广泛的机器学习库之一&#xff0c;其背后的原因是代码的易用性和机器学习开发人员构建机器学习模型所需的几乎所有功能的可用性。在本文中&#xff0c;我们将学习如何使用sklearn在手写数字数据集上训练MLP模型。 其优势是&#xff1a; 它提…

Springboot 多数据源 dynamic-datasource动态添加移除数据源

0.前言 上一篇文章我们讲了如何通过多数据源组件&#xff0c;在Spring boot Druid 连接池项目中配置多数据源&#xff0c;并且通过DS注解的方式切换数据源&#xff0c;《Spring Boot 配置多数据源【最简单的方式】》。但是在多租户的业务场景中&#xff0c;我们通常需要手动的…

【方法】Excel表格如何拆分数据?

当需要把多个数据逐个填到Excel单元格的时候&#xff0c;我们可以利用Excel的数据拆分功能&#xff0c;可以节省不少时间。 小编以下面的数据为例&#xff0c;看看如何进行数据拆分。 首先&#xff0c;要选择数字所在的单元格&#xff0c;然后依次点击菜单栏中的“数据”>…

FFmpeg解码详细流程

介绍 FFmpeg的 libavcodec 模块完成音视频多媒体的编解码模块。老版本的 FFmpeg 将avcodec_decode_video2()作为视频的解码函数 API&#xff0c;将avcodec_decode_audio4()作为音频的解码函数 API&#xff1b;从 3.4版本开始已经将二者标记为废弃过时 API&#xff08;attribut…

Dockerfile构建lamp镜像

1、构建目录 [rootdocker ~]# mkdir compose_lamp [rootdocker ~]# cd compose_lamp/ 2、编写Docekerfile [rootdocker compose_lamp]# vim Dockerfile #基础镜像 FROM centos:7#维护该镜像的用户信息 MAINTAINER Crushlinux <crushlinux163.com>#安装httpd RUN yum -…

反转链表的两种方法

反转链表的两种方法 题目介绍 题目链接 206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 效果图如下所示 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]解法一&#xff1a;迭代方法 解题思路&#xf…

Chapter 10: Dictionaries | Python for Everybody 讲义笔记_En

文章目录 Python for Everybody课程简介DictionariesDictionariesDictionary as a set of countersDictionaries and filesLooping and dictionariesAdvanced text parsingDebuggingGlossary Python for Everybody Exploring Data Using Python 3 Dr. Charles R. Severance 课程…

Spring:JDBCTemplate

JDBCTemplate 概述 概述 JDBC&#xff08;Java DataBase Connectivity&#xff0c;Java 数据库连接&#xff09;&#xff0c; 一 种用于执行 SQL 语句的 Java API&#xff08;Application Programming Interface &#xff0c; 应用程序设计接口 &#xff09;&#xff0c;可以为…

计算机网络(2) --- 网络套接字UDP

计算机网络&#xff08;1&#xff09; --- 网络介绍_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/131967378?spm1001.2014.3001.5501 目录 1.端口号 2.TCP与UDP协议 1.TCP协议介绍 1.TCP协议 2.UDP协议 3.理解 2.网络字节序 发送逻辑…

小白到运维工程师自学之路 第六十六集 (docker 网络模型)

一、概述 Docker网络模型是指Docker容器在网络中的通信方式和组织结构。Docker容器通过网络连接&#xff0c;使得容器之间可以相互通信&#xff0c;并与主机和外部网络进行交互。 在Docker中&#xff0c;有几种不同的网络模型可供选择&#xff1a; 1、主机模式&#xff08;H…

网络安全(黑客)自学建议一一附学习路线

温馨提示&#xff1a;为了避免误入歧途&#xff0c;自学请优先看《网络安全法》。 下面是一些学习建议&#xff1a; 1、多请教有经验的人 切忌钻牛角尖&#xff0c;特别是刚入门的什么都不了解的情况下&#xff0c;可能你花好几天研究的一个东西&#xff0c;人10分钟就能搞定…

DBeaver连MySQL库报错public key retrieval is not allowed

连接报错: public key retrieval is not allowed解决办法&#xff1a; 右击你连接的库进行编辑连接&#xff08;或者直接按F4打开编辑&#xff09; 然后点击驱动属性里面进行设置 找到allowPublicKeyRetrieval属性&#xff0c;把值由false改为true 注&#xff1a;连接成功后如…

部署SpringBoot项目在服务器上,并通过swagger登录

1.项目编译打包 2.上传jar包到服务器并启动 xftp将打包好后的jar包传到虚拟机指定路径 java -jar执行该jar包 3.通过swagger登录 输入后点击下面的执行按钮 会得到一个tocken 4.将tocken放到postman的Headers中 5.修改url 例如我本地测试是http://localhost:8080/接口名&am…