mongodb学习中的困惑,希望能得到大家的帮助。
各位好,我目前遇到个问题,困扰了好久,希望大家能够给个指点。我们项目之前用的mysql,但考虑以后的数据量的发展趋势,考虑用mongodb,但就目前测试的情况而言,处理速度不是很理想,但我又担心是因为我自己测试有误,所以想听听各位的意见,谢谢。
mysql中有三个表:item(id,name)、theme(id,word)、itemtheme(itemid,themeid,word,type,weight);
其中item 和theme是多对多的关系,所以抽出关系表itemtheme用于存放关联关系。
现在的业务逻辑是 做这样的一个操作 需要根据若干个theme.word查出 具有这些 word的item,并按照这若干个word的weight之和倒序排列,取出前200个itemid,举例说:
itemtheme中有
itemidthemeidwordtypeweight
10111china1100
10112gps2200
10113iphone3300
10212gps1100
10213iphone2200
根据上图的模拟数据,我的应用需要做这样的事情:找出 有china 和gps这两个word的itemid,然后对 china和gps这两个word的weight相加,然后按照这个和倒序排列,所以这个实例中得出的结果是 101 300. sql语句 就是
select t1.itemid, (t1.weight + t2.weight) as sumWeight
from itemtheme t1
inner join itemtheme t2 on t1.itemid = t2.itemid
where t1.word= china and t2.word = gps
order by sumWeight desc;
现在我们向移植到mongodb上来,有一个集合叫做item 结构为:
{
"_id" : ObjectId("4faae54a1ba46159a6ca4bfd"),
"itemid" : 101,
"name" : "iphone4s",
"theme" : [
{
"word" : "gps",
"weight" : 200,
"type" : 2
},
{
"word" : "china",
"weight" : 100,
"type" : 1
}
]
}
所以为了完成上面的应用,我就用了mapreduce:
var mr = db.runCommand(
{
mapreduce:"item",
map:function(){
varid = this.itemid;
this.theme.forEach(function(t){
if((t.word =="gps")||(t.word =="china")){
emit(id,{weight:t.weight,word:t.word});
}
});
},
reduce:function(key,values){
sumWeight = 0;
for(var i=0;i<values.length;i++){
var w = values[i].word;
sumWeight += values[i].weight;
}
return{"weight":sumWeight};
},
query:{
"theme.word":
{
$all:
[
"gps",
"china"
]
},
},
out:"INLINE"
});
db[mr.result].find().sort({"value.weight":-1});
目前数据量 是1000万,也就是1000万个item,但目前我发现有几个问题不是很理解:
1. mapreduce的速度没有 mysql的快,请问我这个测试结果正确吗?
2. 有没有什么方法加快mapreduce的速度?
3. 官网说mapreduce 是为了再分布式下处理海量数据,mysql再怎么优化,都是由瓶颈的,所以才会出现nosql,那么要多大的数据量才选择放弃mysql用mongodb呢?
4. 网上有说 用hadoop的mapreduce 通过Mongodb Hadoop Connector 调用mongodb这样能加快处理速度,但就目前而言 我的观察是,hadoop的mapreduce启动时间就需要几秒,而目前我1000万数据用mongodb的mapreduce也是几秒能完成,貌似用hadoop的mapreduce有点大才小用了,不知道我这理解正确不?
ps:我个人觉得,还是数据量的问题,如果需求需要达到TB级别的,那么用mysql就不行了,这时就得考虑nosql 而作为mysql最好的nosql替代品,用mongodb是最合适的,mongodb有点中型nosql的感觉,而hadoop 的hbase 这一套体系有点巨型的感觉。而且我们的设计之前是基于关系数据库的思想,所以用nosql有点牵强,毕竟nosql的数据库是很弱化sql操作的,大部分的设计思想在设计层面就得抛弃关系数据库的思维,而用key-value的思维来设计数据库,但目前我们的应用是不可能变更设计的,所以这也是个很难平衡的问题,mapreduce本身就不是为了追求实时性,不是为了追求速度的,但mongodb本身的性能非常不错,find操作的速度是mysql的5倍以上,但关键是我们的应用用find实现不了,所以非常想听听各位前辈的意见,请多多指教,非常感谢!