Javascript 这看起来像是MapReduce的工作……但我能';我想不出来
我已经为此奋斗了大约两天,任何帮助都将不胜感激。我目前有一个非常大的MongoDB集合(超过1亿个文档),格式如下:Javascript 这看起来像是MapReduce的工作……但我能';我想不出来,javascript,arrays,mongodb,mapreduce,nosql,Javascript,Arrays,Mongodb,Mapreduce,Nosql,我已经为此奋斗了大约两天,任何帮助都将不胜感激。我目前有一个非常大的MongoDB集合(超过1亿个文档),格式如下: [_id] [date] [score] [meta1] [text1] [text2] [text3] [text4] [meta2] 这并不是确切的数据,为了这篇文章的目的,我对它进行了一些模糊处理,但是模式是相同的,不,数据的格式不能更改,这就是它的方式 其中有大量重复条目,一个作业每天运行一次,向数据库中添加数百万条条目,这些条目在文本字段中可能具有相同的数据,但分数、
[_id]
[date]
[score]
[meta1]
[text1]
[text2]
[text3]
[text4]
[meta2]
这并不是确切的数据,为了这篇文章的目的,我对它进行了一些模糊处理,但是模式是相同的,不,数据的格式不能更改,这就是它的方式
其中有大量重复条目,一个作业每天运行一次,向数据库中添加数百万条条目,这些条目在文本字段中可能具有相同的数据,但分数、元1和元2字段的值不同。因此,我需要消除重复,并将所有内容塞入一个集合中,而不存在重复文本:
首先,我将连接文本字段并散列结果,这样就不会有包含相同文本字段的重复项(这一部分很简单,已经可以工作了)
这就是我正在努力的地方:生成的集合将有一个包含每个唯一meta1的数组,而meta1又将是一个包含与之匹配的日期和分数的数组
因此,如果我现在收藏了以下三份文件:
[_id] => random mongoid
[date] => 12092010
[score] => 3
[meta1] => somemetadatahere
[text1] => foo
[text2] => bar
[text3] => foo2
[text4] => bar2
[meta2] => uniquemeta2data
[_id] => random mongoid
[date] => 12092010
[score] => 5
[meta1] => othermetadata
[text1] => foo
[text2] => bar
[text3] => foo2
[text4] => bar2
[meta2] => uniquemeta2data1
[_id] => random mongoid
[date] => 12102010
[score] => 7
[meta1] => somemetadatahere (same meta1 as the first document)
[text1] => foo
[text2] => bar
[text3] => foo2
[text4] => bar2
[meta2] => uniquemeta2data
它们应该减少到这个集合(缩进是嵌套文档/数组)。数据数组中的键来自原始集合中meta1字段的值:
[_id]=> (md5 hash of all the text fields)
[text1] => foo
[text2] => bar
[text3] => foo2
[text4] => bar2
[datas]
[somemetadatahere]
[meta2] => uniquemeta2data
[scores]
[12092010]=>3
[12102010]=>7
[othermetadata]
[meta2] => uniquemeta2data1
[scores]
[12092010]=>3
对于MapReduce作业来说,这似乎是一个完美的用例,但对于如何实现这一点,我的头脑有些困难
有人愿意帮我解决这个问题吗?我认为MapReduce的问题似乎是直截了当的,这意味着我可能误解了你的问题。这就是我的看法 根据文本散列对原始集合进行分割。让每个部分集中于组合结果子集 这里有一些来自 我将尝试编辑此内容以适合您的问题
function myMapper(key, value) {
var ret = [];
var words = normalizeText(value).split(' ');
for (var i=0; i<words.length; i++) {
ret.push({key:words[i], value:1});
}
return ret;
}
function myReducer(intermediateKey, values) {
var sum = 0;
for (var i=0; i<values.length; i++) {
sum += values[i];
}
return {key:intermediateKey, value:sum};
}
function normalizeText(s) {
s = s.toLowerCase();
s = s.replace(/[^a-z]+/g, ' ');
return s;
}
var i = {};
i.atxt = "The quick brown fox jumped over the lazy grey dogs.";
i.btxt = "That's one small step for a man, one giant leap for mankind.";
i.ctxt = "Mary had a little lamb, Its fleece was white as snow; And everywhere that Mary went, The lamb was sure to go.";
var out = mapReduce(i, myMapper, myReducer);
函数myMapper(键,值){
var-ret=[];
var words=normalizeText(值).split(“”);
对于(var i=0;i基本上,这是与mapreduce中众所周知的词频问题相同的问题,但不是使用单词,而是使用哈希(以及对原始条目的引用):
- 映射:获取每个条目的散列并将其映射到耦合(散列,1)。(要检索原始条目:创建一个对象并将原始条目用作属性)
- Reduce:所有散列条目将被收集到同一个bucket中,
计算每对的值(散列,1)
- 输出散列、原始条目(存储在对象中)和计数
类比:猫坐在垫子上
地图:
- (散列(the),1)
- 类别->(哈希(类别),1)
- sat->(散列(sat),1)
- on->(哈希(on),1)
- (散列(the),1)
- mat->(散列(mat),1)
中级:
- (散列(the),1)
- 类别->(哈希(类别),1)
- sat->(散列(sat),1)
- on->(哈希(on),1)
- (散列(the),1)
- mat->(散列(mat),1)
减少:
- (hash(the),2)
- (哈希(cat),1)
- (散列(sat),1)
- (hash(on),1)
- (散列(mat),1)
嗯,我也是一个MapReduce新手,所以直接告诉你的可能不是我,我的主要问题是reduce函数。你能更详细地解释一下划分原始集合的意思吗?看看我添加的示例,myMapper函数将值划分为单词。相反,你想基于文本值散列将集合划分为子集。