>我在计算单词时遇到问题我想在项目中数字.log.主题。例如(计数[A],[B],[C]。我搜索了如何使用地图减少。但我不明白如何使用它来获得我想要的结果。
{
"_id": ObjectID("569f3a3e9d2540764d8bde59"),
"A": "book",
"server": "us",
"projects": [
{
"domainArray": [
{
~~~~
}
],
"log": [
{
~~~~~,
"subject": "[A][B]I WANT THIS"
}
],
"before": "234234234"
},
{
"domainArray": [
{
~~~~
}
],
"log": [
{
~~~~~,
"subject": "[B][C]I WANT THIS"
}
],
"before": "234234234"
},....
] //end of projects
}//end of document
这是使用正则表达式并根据源字符串测试每个字符串并发出结果的发现计数的基本原则。在mapReduce术语中,您希望"映射器"函数可能为每个"术语"发出多个值作为键,以及每个文档中存在的每个数组元素。
所以你基本上想要一个正则表达式的源数组来处理(可能只是一个单词列表(来迭代和测试,并迭代每个数组成员。
基本上是这样的:
db.collection.mapReduce(
function() {
var list = ["the", "quick", "brown" ]; // words you want to count
this.projects.forEach(function(project) {
project.log.forEach(function(log) {
list.forEach(function(word) {
var res = log.subject.match(new RegExp("\b" + word + "\b","ig"));
if ( res != null )
emit(word,res.length); // returns number of matches for word
});
});
});
},
function(key,values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
)
因此,循环处理文档中的数组元素,然后应用每个单词来查找正则表达式进行测试。.match()
方法将在字符串中返回匹配项数组,如果找到 true,则返回null
。请注意正则表达式的i
和g
选项,以便搜索不区分大小写的匹配项,而不仅仅是第一个匹配项。如果文本也包含换行符,则可能需要多行m
。
如果未返回null
,则我们将当前单词作为"键"发出,并将计数作为匹配数组的长度。
然后,化简器从映射器中的这些emit
调用中获取所有输出值,并简单地将发出的计数相加。
结果将是一个文档,由提供的每个"单词/术语"和集合中检查字段中的总出现次数键入。对于更多字段,只需添加更多逻辑来汇总结果,或者类似地只是在映射器中保持"发射"并让化简器完成工作。
请注意 ' "\b" represents a word boundary expression to wrap each term escaped by
以便从字符串构造表达式。您需要这些来区分"the"
和"then"
,例如,通过指定单词/术语的结尾位置。
此外,作为正则表达式,像 []
这样的字符是保留的,所以如果你真的在寻找这样的字符串,你同样会转义,即:
"[A]"
但是,如果您确实这样做了,请删除单词边界字符:
new RegExp( "[A]", "ig" )
因为这本身就足够完全匹配。