我一直在使用以下MySQL命令从日志数据构建热图。但是,我有一个存储在Mongo数据库中的新数据集,我需要运行相同的命令。
select concat(a.packages '&' b.packages) "Concurrent Packages",
count(*) "Count"
from data a
cross join data b
where a.packages<b.packages and a.jobID=b.jobID
group by a.packages, b.packages
order by a.packages, b.packages;
请记住,在查询之前,表a和b不存在。但是,它们是从数据表的packages列创建的,其中jobID作为我要检查匹配的字段。换句话说,如果两个包在同一个作业中,我想在并发使用计数中添加一个条目。如何在Mongo中生成类似的查询?
答案 0 :(得分:2)
这不是不同文件的“加入”;它是一个文档中的一个操作,可以在MongoDB中完成。
You have a SQL TABLE "data" like this:
JobID TEXT,
package TEXT
在MongoDB中存储它的最佳方法是一个名为“data”的集合,每个JobID包含一个包含一系列包的文档:
{
_id: <JobID>,
packages: [
"packageA",
"packageB",
....
]
}
[注意:您还可以将数据表实现为MongoDB中的一个文档,其中包含一个包含每个包数组的作业数组。建议不要这样做,因为您可能会达到16MB的文档大小限制,并且嵌套数组不会(还)得到不同查询的良好支持 - 如果您还希望将数据用于其他目的]
现在,如何获得这样的结果?
{ pair: [ "packageA", "packageB" ], count: 20 },
{ pair: [ "packageA", "packageC" ], count: 11 },
...
由于MongoDB中没有内置的“交叉连接”两个数组,你必须在mapReduce()的map函数中编写它,将每对包作为键发送:
mapf = function () {
that = this;
this.packages.forEach( function( p1 ) {
that.packages.forEach( function( p2 ) {
if ( p1 < p2 ) {
key = { "pair": [ p1, p2 ] };
emit( key, 1 );
};
});
});
};
[注意:如果包数组已经排序,这可以进行优化]
reduce函数只不过是总结每个键的计数器:
reducef = function( key, values ) {
count = 0;
values.forEach( function( value ) { count += value } );
return count;
};
因此,对于此示例集合:
> db.data.find()
{ "_id" : "Job01", "packages" : [ "pA", "pB", "pC" ] }
{ "_id" : "Job02", "packages" : [ "pA", "pC" ] }
{ "_id" : "Job03", "packages" : [ "pA", "pB", "pD", "pE" ] }
we get the following result:
> db.data.mapReduce(
... mapf,
... reducef,
... { out: 'pairs' }
... );
{
"result" : "pairs",
"timeMillis" : 443,
"counts" : {
"input" : 3,
"emit" : 10,
"reduce" : 2,
"output" : 8
},
"ok" : 1,
}
> db.pairs.find()
{ "_id" : { "pair" : [ "pA", "pB" ] }, "value" : 2 }
{ "_id" : { "pair" : [ "pA", "pC" ] }, "value" : 2 }
{ "_id" : { "pair" : [ "pA", "pD" ] }, "value" : 1 }
{ "_id" : { "pair" : [ "pA", "pE" ] }, "value" : 1 }
{ "_id" : { "pair" : [ "pB", "pC" ] }, "value" : 1 }
{ "_id" : { "pair" : [ "pB", "pD" ] }, "value" : 1 }
{ "_id" : { "pair" : [ "pB", "pE" ] }, "value" : 1 }
{ "_id" : { "pair" : [ "pD", "pE" ] }, "value" : 1 }
有关mapReduce的详细信息,请参阅:http://docs.mongodb.org/manual/reference/method/db.collection.mapReduce/和http://docs.mongodb.org/manual/applications/map-reduce/
答案 1 :(得分:1)
你做不到。 Mongo没有加入。从迁移SQL到Mongo比迁移查询要多得多。
通常,您将在同一记录中包含所有相关信息(而不是规范化信息并使用连接选择它)。反规范化!