首页 > 其他分享 >大数据环境下 实现每天千万级地址关联 10万/秒

大数据环境下 实现每天千万级地址关联 10万/秒

时间:2024-04-02 13:59:07浏览次数:22  
标签:10 getString res 千万级 地址 && address put null

地名作为最常用的社会公共信息,不仅与人们的日常生活息息相关,而且是政府行政行为、经济建设不可缺少的基础信息资源。在政务系统中有许多需要将业务地址关联到标准地址的场景,addresstool致力于解决地址关联匹配算法中的速度和准确性问题。经实测,单核addresstool的地址关联速度在5000/秒-20000/秒之间(取决于业务地址质量),关联匹配正确率达到98%。hadoop分布式环境地址关联匹配速度能达到10万+/秒(具体取决与大数据节点数和地址质量,节点足够。每秒实现百万级地址关联)。

本文大数据环境为hive数据库,通过udf将addresstool封装,最后实现分布式计算。
直接上代码

public class AddressLink extends GenericUDF {
    private PrimitiveObjectInspector addressIO;
    private static AddressTool addressTool;



    private String bld(String building){
        if(building!=null&&!building.isEmpty() ){
            if(building.endsWith("栋")||building.endsWith("幢")){
                return building.substring(0,building.length()-1);
            }else if(building.endsWith("号楼")){
                return building.substring(0,building.length()-2);
            }
        }

        return building;
    }

    private String unit(String unit){
        if(unit!=null&&!unit.isEmpty() ){
            if(unit.endsWith("单元")){
                return unit.substring(0,unit.length()-2);
            }
        }

        return unit;
    }

    private String room(String room){
        if(room!=null&&!room.isEmpty() ){
            if(room.endsWith("室")||room.endsWith("户")){
                return room.substring(0,room.length()-1);
            }
        }

        return room;
    }


    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        if (arguments[0] instanceof ObjectInspector) {
            addressIO = (PrimitiveObjectInspector) arguments[0];
        }else{
            throw new UDFArgumentLengthException("The function GetMapValue accepts  1 argument. simple: GetSqName(sq_name)");
        }
        addressTool = new AddressTool();
        DataTable data = new DataTable();
        try{
            //注册Driver
            String driver = "org.postgresql.Driver";//prop.getProperty("driver");
            String url = "jdbc:postgresql://*****:5432/postgres";//prop.getProperty("url");
            String username = "******";//prop.getProperty("user");
            String password = "******";//prop.getProperty("password");
            Class.forName(driver);
            Connection connection = DriverManager.getConnection(url, username, password);
            Statement statement = connection.createStatement();

            // 数据初始化
            ResultSet res = statement.executeQuery("select id,province,city,county,town,community,road,road_no,aoi,sub_aoi,building,unit,room,address from st_address order by aoi,road,road_no");
            int cnt = 0;
            while (res.next()) {
                HashMap<String,String> mp = new HashMap<>();
                if(res.getString("id")!=null&& !Objects.equals(res.getString("id"), "")){mp.put("id",res.getString("id"));}
                if(res.getString("province")!=null&& !Objects.equals(res.getString("province"), "")){mp.put("province",res.getString("province"));}
                if(res.getString("city")!=null&& !Objects.equals(res.getString("city"), "")){mp.put("city",res.getString("city"));}
                if(res.getString("county")!=null&& !Objects.equals(res.getString("county"), "")){mp.put("county",res.getString("county"));}
                if(res.getString("town")!=null&& !Objects.equals(res.getString("town"), "")){mp.put("town",res.getString("town"));}
                if(res.getString("community")!=null&& !Objects.equals(res.getString("community"), "")){mp.put("community",res.getString("community"));}
                if(res.getString("road")!=null&& !Objects.equals(res.getString("road"), "")){mp.put("road",res.getString("road"));}
                if(res.getString("road_no")!=null&& !Objects.equals(res.getString("road_no"), "")){mp.put("road_no",res.getString("road_no"));}
                if(res.getString("aoi")!=null&& !Objects.equals(res.getString("aoi"), "")){mp.put("aoi",res.getString("aoi"));}
                if(res.getString("sub_aoi")!=null&& !Objects.equals(res.getString("sub_aoi"), "")){mp.put("sub_aoi",res.getString("sub_aoi"));}
                if(res.getString("building")!=null&& !Objects.equals(res.getString("building"), "")){mp.put("building",bld(res.getString("building")));}
                if(res.getString("unit")!=null&& !Objects.equals(res.getString("unit"), "")){mp.put("unit",unit(res.getString("unit")));}
                if(res.getString("room")!=null&& !Objects.equals(res.getString("room"), "")){mp.put("room",room(res.getString("room")));}
                if(res.getString("address")!=null&& !Objects.equals(res.getString("address"), "")){mp.put("address",res.getString("address"));}
                data.addAddressDic(mp);
                cnt = cnt + 1;
            }

            //标准数据地址数据加载到addresstool
            data.initData(addressTool);
            data = null;
            statement.close();
            connection.close();

        } catch (Exception throwables) {
            throwables.printStackTrace();
        }

        return ObjectInspectorFactory.getStandardMapObjectInspector(
                PrimitiveObjectInspectorFactory.javaStringObjectInspector,
                PrimitiveObjectInspectorFactory.javaStringObjectInspector);
    }

    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
        if(arguments[0].get()==null){
            return null;
        }


        String address =  PrimitiveObjectInspectorUtils.getString(arguments[0].get(), this.addressIO);
        // 中文地址中的异常字符预处理
        while(address.contains(" ")){address = address.replace(" ","");}
        while(address.contains("--")){address = address.replace("--","-");}
        while(address.contains("——")){address = address.replace("——","-");}
        while(address.contains("- ")){address = address.replace("- ","-");}
        while(address.contains(" -")){address = address.replace(" -","-");}
        while(address.contains("— ")){address = address.replace("— ","-");}
        while(address.contains(" —")){address = address.replace(" —","-");}


        // 地址关联
        StandardAddress stdAddress = addressTool.getStdAddress(address);
        Map<String,String> result = stdAddress.getStdAddress();
        // 地址级别判断
        if(stdAddress.addressLevel!=null&& !stdAddress.addressLevel.equals("")){
            result.put("addressLevel",stdAddress.addressLevel);
        }else{
            result.put("addressLevel","未知");
        }

        // 地址关联级别判断
        if(stdAddress.linkLevel!=null&& !stdAddress.linkLevel.equals("")){
            result.put("linkLevel",stdAddress.linkLevel);
        }else{
            result.put("linkLevel","未关联");
        }


        return result;
    }


    @Override
    public String getDisplayString(String[] children) {
        return "Address(" + children[0] + ")";
    }

}

addresstool在分布式节点下计算速度超级快,经实测,1千万地址数据在sparksql调用udf方式,耗时3.5分钟。5千万数据耗时8分钟。

详细代码见git上AddressLink类

通过addresstool与大数据结合,成功实现每日千万级业务地址全量关联更新。

java资源下载
https://download.csdn.net/download/u011024436/89035851
源码学习
https://gitee.com/addresstool/address

使用中有问题或者建议,欢迎联系邮箱[email protected]

标签:10,getString,res,千万级,地址,&&,address,put,null
From: https://blog.csdn.net/u011024436/article/details/137244190

相关文章

  • 各个官方开发文档地址收录
    开发文档:前端富文本组件wangEditor:https://www.wangeditor.com/v5/for-frame.html#%E4%BD%BF%E7%94%A8-1element-plus: https://element-plus.org/zh-CN/component/layout.htmlelement-UI:https://element.eleme.io/#/zh-CN/component/radio微信开放文档:https://developers.......
  • C语言程序10题
    第101题(10.0分)          难度:易       第2章/*-------------------------------------------------------【程序填空】---------------------------------------------------------功能:计算平均成绩并统计90分以上人数。----------------------......
  • Kylin Desktop V10部署达梦数据库(DM8)
    1.环境处理器:飞腾D2000/8E8C内存:16GB系统:银河麒麟桌面版操作系统(国防版)V10达梦数据库:dm8_20231226_FTarm2000_kylin10_sp1_642.软件下载链接:https://www.dameng.com/list_103.html3.环境部署我这里已经下载好了(软件、环境部署脚本),需拷贝至桌面运行no1.sh,安装完成后运行n......
  • DreamOJ D10009
    DreamOJD10009标签DP线段树均摊题意给定一个包含\(n\)个节点根为\(1\)的树,和一个序列\(s\)。如果满足以下两个条件,那么一个包含\(k\)条简单路径的可重集合认为是合法的。这个可重集合中所有的路径都是从根节点\(1\)出发。令\(c_i\)为覆盖节点\(i\)的路径......
  • 零基础10 天入门 Web3之第2天
    10天入门Web3之第2天Web3 是互联网的下一代,它将使人们拥有自己的数据并控制自己的在线体验。Web3基于区块链技术,该技术为安全、透明和可信的交易提供支持。我准备做一个10天的学习计划,可帮助大家入门Web3:一、这是第二天,首先免费下载一下两篇白皮书尽量一口气看完它:比......
  • 5.103 BCC工具之filegone.py解读
    一,工具简介filegone 追踪文件消失的原因,无论是被删除还是被重命名。二,代码示例#!/usr/bin/pythonfrom__future__importprint_functionfrombccimportBPFimportargparsefromtimeimportstrftime#argumentsexamples="""examples:./filegone......
  • 5.102 BCC工具之filelife.py解读
    一,工具简介filelife 追踪短生命周期的文件:那些在追踪过程中被创建然后又被删除的文件。二,代码示例#!/usr/bin/envpythonfrom__future__importprint_functionfrombccimportBPFimportargparsefromtimeimportstrftime#argumentsexamples="""examples:......
  • 比特币钱包地址生成问题
    l 问题描述:比特币钱包负责管理私钥,在收款时往往会展示钱包地址。钱包地址的生成步骤如下(如图所示):获取私钥对应的公钥,再根据公钥计算公钥哈希值(ripemd160函数),得到一个20字节长度的字节数组;1.在公钥哈希值前面添加比特币地址版本号(1个字节,当前默认为0x00);2.对步骤1得到的数据进......
  • 判断ip地址是否合法(美团2024届秋招笔试第三场编程真题)
    核心思想大模拟-。-,还是不够细心,面向样例编程,一路错过去的。写得太丑了凑合看吧。代码importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){finallongMOD=(long)(1e9+7);Scannerscanner=newScanner(Syste......
  • stm32cubeide 调试非 0x08000000 地址程序配置
    使用stm32cubeide调试非0x08000000,我们需要一些配置.ld链接脚本条件编译目前如果要修改程序的启动地址需要修改两个地方system_stm32f103xx.c中的VECT_TAB_OFFSET,可通过宏定义开启或者关闭.ld链接脚本,可通过宏进行条件编译,也可以直接修改ld,创建不同的链接脚本文件,创建......