JS創(chuàng)建MongoDB測試數據(一)
大致需求:
模擬1萬個設備,ID號從1到10000;
每個設備有一個檔案,包括設備ID、手機號、車牌號、駕駛員;
100個設備組成一組,同組設備具有相同的檔案;
每個設備有10萬條數據,每條數據包括設備ID、油耗、里程、溫度、速度,時間。
用到的工具
MongoDB Server
MongoChef 一個很好用的MongoDB客戶端
Notepad++ 用來編輯JS代碼
小總結
插入大量數據要用insertMany函數,insert函數會非常慢,即使用了批量插入也還是比較慢,插入1000萬條數據用了將近20分鐘,如果按原計劃10億條,那要用掉差不多1天半,所以還有很大優(yōu)化空間。
源代碼
運行方法: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(){
//地區(qū),用于生成車牌號
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)]; //第一位地區(qū)簡稱
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 = ["趙", "錢", "孫", "李", "周", "吳", "鄭", "王", "馮", "陳",
"褚", "衛(wèi)", "蔣", "沈", "韓", "楊", "朱", "秦", "尤", "許",
"何", "呂", "施", "張", "孔", "曹", "嚴", "華", "金", "魏",
"陶", "姜", "戚", "謝", "鄒", "喻", "柏", "水", "竇", "章",
"云", "蘇", "潘", "葛", "奚", "范", "彭", "郎", "魯", "韋",
"昌", "馬", "苗", "鳳", "花", "方", "俞", "任", "袁", "柳",
"酆", "鮑", "史", "唐", "費", "廉", "岑", "薛", "雷", "賀",
"倪", "湯", "滕", "殷", "羅", "畢", "郝", "鄔", "安", "常",
"樂", "于", "時", "傅", "皮", "卞", "齊", "康", "伍", "余",
"元", "卜", "顧", "孟", "平", "黃", "和", "穆", "蕭", "尹"
];
var givenNames = ["子璇", "淼", "國棟", "夫子", "瑞堂", "甜", "敏", "尚", "國賢", "賀祥", "晨濤",
"昊軒", "易軒", "益辰", "益帆", "益冉", "瑾春", "瑾昆", "春齊", "楊", "文昊",
"東東", "雄霖", "浩晨", "熙涵", "溶溶", "冰楓", "欣欣", "宜豪", "欣慧", "建政",
"美欣", "淑慧", "文軒", "文杰", "欣源", "忠林", "榕潤", "欣汝", "慧嘉", "新建",
"建林", "亦菲", "林", "冰潔", "佳欣", "涵涵", "禹辰", "淳美", "澤惠", "偉洋",
"涵越", "潤麗", "翔", "淑華", "晶瑩", "凌晶", "苒溪", "雨涵", "嘉怡", "佳毅",
"子辰", "佳琪", "紫軒", "瑞辰", "昕蕊", "萌", "明遠", "欣宜", "澤遠", "欣怡",
"佳怡", "佳惠", "晨茜", "晨璐", "運昊", "汝鑫", "淑君", "晶瀅", "潤莎", "榕汕",
"佳鈺", "佳玉", "曉慶", "一鳴", "語晨", "添池", "添昊", "雨澤", "雅晗", "雅涵",
"清妍", "詩悅", "嘉樂", "晨涵", "天赫", "玥傲", "佳昊", "天昊", "萌萌", "若萌",
"澤民", "國強", "勝利", "小凡", "碧瑤", "書書", "京雨", "衛(wèi)東", "小佳", "長江"
];
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);