JS创建MongoDB测试数据(一)

JS创建MongoDB测试数据(一)

大致需求:

模拟1万个设备,ID号从1到10000;
每个设备有一个档案,包括设备ID、手机号、车牌号、驾驶员;
100个设备组成一组,同组设备具有相同的档案;
每个设备有10万条数据,每条数据包括设备ID、油耗、里程、温度、速度,时间。

用到的工具

MongoDB Server
MongoChef 一个很好用的MongoDB客户端
Notepad++ 用来编辑JS代码

小总结

插入大量数据要用insertMany函数,insert函数会非常慢,即使用了批量插入也还是比较慢,插入1000万条数据用了将近20分钟,如果按原计划10亿条,那要用掉差不多1天半,所以还有很大优化空间。

源代码

运行方法:mongo shell支持js脚本,所以可以直接跑。MongoChef连上数据库,打开IntelliShell,把代码复制粘贴过去,点击运行即可。也可以保存为.js文件,IntelliShell中打开文件,点击运行。

//生成随机手机号
function getRandPhone(){
    var heads = ["134","138","139","150","151","152","157","158","159","170","189"];
    var phone = heads[Math.floor(Math.random()*heads.length)];
    var numbers = [1,2,3,4,5,6,7,8,9];
    for(var i=0; i<8; i++){
        phone+=numbers[Math.floor(Math.random()*numbers.length)];
    }
    return phone;
}

//生成车牌号
function getRandPlate(){
    //地区,用于生成车牌号
    var loc = ["川","渝","贵","陕","京","沪","粤","津","赣","湘","鄂"];
    //字母,用于生成车牌号
    var chars = ["A","B","C","D"];
    //数字,用于生成车牌号
    var numbers = [1,2,3,4,5,6,7,8,9];
    var plate = "";
    plate += loc[Math.floor(Math.random()*loc.length)]; //第一位地区简称
    plate += chars[Math.floor(Math.random()*chars.length)]; //第二位字母简称
    //4位数字
    for(var i=0; i<4; i++){
        plate+=numbers[Math.floor(Math.random()*numbers.length)];
    }
    return plate;
}

//生成名字
function getRandName(){
    var familyNames = ["赵",  "钱",  "孙",  "李",  "周",  "吴",  "郑",  "王",  "冯",  "陈",  
        "褚",  "卫",  "蒋",  "沈",  "韩",  "杨",  "朱",  "秦",  "尤",  "许",
        "何",  "吕",  "施",  "张",  "孔",  "曹",  "严",  "华",  "金",  "魏",  
        "陶",  "姜",  "戚",  "谢",  "邹",  "喻",  "柏",  "水",  "窦",  "章",
        "云",  "苏",  "潘",  "葛",  "奚",  "范",  "彭",  "郎",  "鲁",  "韦",  
        "昌",  "马",  "苗",  "凤",  "花",  "方",  "俞",  "任",  "袁",  "柳",
        "酆",  "鲍",  "史",  "唐",  "费",  "廉",  "岑",  "薛",  "雷",  "贺",  
        "倪",  "汤",  "滕",  "殷",  "罗",  "毕",  "郝",  "邬",  "安",  "常",
        "乐",  "于",  "时",  "傅",  "皮",  "卞",  "齐",  "康",  "伍",  "余",  
        "元",  "卜",  "顾",  "孟",  "平",  "黄",  "和",  "穆",  "萧",  "尹"
        ];
    var givenNames = ["子璇", "淼", "国栋", "夫子", "瑞堂", "甜", "敏", "尚", "国贤", "贺祥", "晨涛", 
        "昊轩", "易轩", "益辰", "益帆", "益冉", "瑾春", "瑾昆", "春齐", "杨", "文昊", 
        "东东", "雄霖", "浩晨", "熙涵", "溶溶", "冰枫", "欣欣", "宜豪", "欣慧", "建政", 
        "美欣", "淑慧", "文轩", "文杰", "欣源", "忠林", "榕润", "欣汝", "慧嘉", "新建", 
        "建林", "亦菲", "林", "冰洁", "佳欣", "涵涵", "禹辰", "淳美", "泽惠", "伟洋", 
        "涵越", "润丽", "翔", "淑华", "晶莹", "凌晶", "苒溪", "雨涵", "嘉怡", "佳毅", 
        "子辰", "佳琪", "紫轩", "瑞辰", "昕蕊", "萌", "明远", "欣宜", "泽远", "欣怡", 
        "佳怡", "佳惠", "晨茜", "晨璐", "运昊", "汝鑫", "淑君", "晶滢", "润莎", "榕汕", 
        "佳钰", "佳玉", "晓庆", "一鸣", "语晨", "添池", "添昊", "雨泽", "雅晗", "雅涵", 
        "清妍", "诗悦", "嘉乐", "晨涵", "天赫", "玥傲", "佳昊", "天昊", "萌萌", "若萌",
        "泽民", "国强", "胜利", "小凡", "碧瑶", "书书", "京雨", "卫东", "小佳", "长江"
        ];
    var name = familyNames[Math.floor(Math.random()*familyNames.length)];
    name+=givenNames[Math.floor(Math.random()*givenNames.length)];
    return name;
}

//var plate =  getRandPlate();
//print(plate);

//var phone = getRandPhone();
//print(phone);

//var name = getRandName();
//print(name);

/**生成油耗
*@param base 油耗基准值
*/
function getFuelConsum(base){
    var trueRange = [base-2, base+2]; //假定偏离基准不超过2
    var fuelConsum = Math.random()*(trueRange[1]-trueRange[0]);
    fuelConsum += trueRange[0];
    return Math.round(fuelConsum*100)/100; //转成2位小数
}

/**生成设备数据
* @param devNum 设备数量
* @param groupNum 每组设备的数量,同一组设备的档案相同
* @param dataNum 每个设备的数据数量
*/
function genDeviceData(devNum,groupNum,dataNum){
    use test;
    for(var i=0; i<devNum/groupNum; i++){
        var devDocs = new Array();
        var phone = getRandPhone();
        var plate =  getRandPlate();
        var driver = getRandName();
        for(var l=1; l<=groupNum; l++) {
            //生成档案
            var deviceId = (l+ i*groupNum).toString();
            devDocs[l-1]= {"deviceId":deviceId,"phone":phone,"plate":plate,"driver":driver};
            //设置基准
            var range = [5,15]; //油耗范围
            var base = range[0] + Math.round(Math.random()*(range[1]-range[0])); //油耗基准值
            var rangeM = [5000,200000]; //行驶里程范围
            var baseM = rangeM[0] + Math.round(Math.random()*(rangeM[1]-rangeM[0])); //里程基准值
            var rangeT = [5,100];//温度范围
            var rangeS = [0,200];//速度范围
            var now = Date.parse(new Date());//1970.1.1至今的毫秒数
            //随机取一个时间作为基准
            var timeBase = Math.round(Math.random()*now);
            //生成数据,每次批量插入100条
            for(var j=0; j<dataNum/100; j++){
                var docs = new Array();
                for(var k=0; k<100; k++) {
                    var fuelConsum = getFuelConsum(base);
                    var mileage = baseM+j*100+k; //每次递增1
                    var temperature = Math.random()*(rangeT[1]-rangeT[0]);
                    temperature = Math.round(temperature*10)/10; //转成1位小数
                    var speed = Math.random()*(rangeS[1]-rangeS[0]);
                    speed = Math.round(speed); //转成整数
                    var timestamp = timeBase+60*(100*j+k);//每次递增60秒
                    docs[k] = {"deviceId":deviceId,"fuelConsum":fuelConsum,"mileage":mileage,"temperature":temperature,"speed":speed,"timestamp":timestamp};
                }
                db.data.insertMany(docs);
            }
        }
        db.archive.insertMany(devDocs);
    }
}

//1000个设备,每组10个,每个设备1万条数据
genDeviceData(1000,10,10000);
    原文作者:quiterr
    原文地址: https://www.jianshu.com/p/cafd28ef9b30
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞