我是mongo db的新手,请原谅我,如果这是相当微不足道的话。我真的很感激帮助。
这个想法是在某些特定值上生成直方图。在那种情况下,某些文件的mime类型。为此,我正在使用地图减少工作。
我有一个mongo,文件格式如下:
{
"_id" : ObjectId("4fc5ed3e67960de6794dd21c"),
"name" : "some name",
"uid" : "some app specific uid",
"collection" : "some name",
"metadata" : [
{
"key" : "key1",
"value" : "Plain text",
"status" : "SINGLE_RESULT",
},
{
"key" : "key2",
"value" : "text/plain",
"status" : "SINGLE_RESULT",
},
{
"key" : "key3",
"value" : 3469,
"status" : "OK",
}
]
}
请注意,几乎每个文档中都有更多元数据键值。
地图减少工作
我尝试了以下操作:
function map() {
var mime = "";
this.metadata.forEach(function (m) {
if (m.key === "key2") {
mime = m.value;}
});
emit(mime, {count:1});
}
function reduce() {
var res = {count:0};
values.forEach(function (v) {res.count += v.count;});
return res;
}
db.collection.mapReduce(map, reduce, {out: { inline : 1}})
这似乎适用于少量文档(~15K),但问题是迭代所有元数据键值需要在映射阶段花费大量时间。在更多文档(〜1Mio)上运行此操作时,操作将永远持续。
所以我的问题是: 有没有什么方法可以直接发出mime类型(值)而不是迭代所有键并选择它?或者是否有更好的方法来编写地图缩减功能。
像emit(this.metadata.value {$ where this.metadata.key:“key2”})或类似内容......
感谢您的帮助!
答案 0 :(得分:6)
两个想法......
首先想到:你对这个文档架构的依恋程度如何?您是否可以将元数据字段值作为嵌入式文档而不是嵌入式数组,如下所示:
{
"_id" : ObjectId("4fc5ed3e67960de6794dd21c"),
"name" : "some name",
"uid" : "some app specific uid",
"collection" : "some name",
"metadata" : {
"key1" : {
"value" : "Plain text",
"status" : "SINGLE_RESULT"
},
"key2": {
"value" : "text/plain",
"status" : "SINGLE_RESULT"
},
"key3" : {
"value" : 3469,
"status" : "OK"
}
}
}
然后你的地图步骤完全取消了循环:
function map() {
emit( this.metadata["key2"].value, { count : 1 } );
}
此时,您甚至可以将其转换为“组”命令而不是“mapReduce”。
第二个想法:如果没有这样的模式更改,特别是如果“key2”出现在元数据数组的早期,那么一旦找到密钥就可以至少退出循环以节省一些迭代,如下所示:
function map() {
var mime = "";
this.metadata.forEach(function (m) {
if (m.key === "key2") {
mime = m.value;
break;
}
});
emit(mime, {count:1});
}
不确定任何一条路径是否是胜利的关键,但希望有用的想法。祝你好运!