假设我有一些看起来像这样的数据。
[
{ "foo": 1, "bar": "a" },
{ "foo": 2, "bar": "b" },
{ "foo": 3, "bar": "b" },
{ "foo": 4, "bar": "a" }
]
我希望按bar
对行进行分组,并将匹配结果存储在对象/地图中的bar值下,如数据结构,就像这样。
{
"a": [{ "foo": 1, "bar": "a" }, { "foo": 4, "bar": "a" }],
"b": [{ "foo": 2, "bar": "b" }, { "foo": 3, "bar": "b" }]
}
Mongo有哪些功能来处理这种转换(或类似的东西)?
我正在使用node.js编写一个Web应用程序,并且我已经设法在javascript(我知道......)中进行了这种转换,但是每当用户查询过于开放且几乎没有约束时,就会产生结果在内存过度分配中,因为我处理大约超过250,000行。当查询返回少于10000行时,我的分组方法有效。
在此之后,我意识到我应该让Mongo为我处理这个问题,特别是因为它导致服务器挂起直到分组完成。我只是不确定如何进行这样的转变。
在我尝试通过网络套接字传输数据后,客户端上的网络工作人员执行此操作之前通过网络工作者分割工作,但它使界面非常明显,&它可能不会在压力下站起来。但至少这不会阻止服务器,也不会导致服务器崩溃。
假设是否有bar
的所有可能值的列表(我已存储在集合中),我应该进行多次查询吗? &安培;从结果中形成数据结构?
答案 0 :(得分:2)
aggregation framework相当简单,也是最快的选择,因为聚合框架是本机代码实现,其中像mapReduce这样的东西需要在进程中调用JavaScript解释器:
db.collection.aggregate([
{ "$group": {
"_id": "$bar",
"values": { "$push": { "foo": "$foo", "bar": "$bar" } }
}
])
这需要您对文档结构有所了解。如果您需要更灵活的不同文档,那么您可以使用mapReduce:
db.collection.mapReduce(
function() {
emit( this.bar, this );
},
function(key, values) {
return { values: values };
},
{ "out": { "inline": 1 }
)
不如你的结果那么漂亮,但它完成了工作。
这里唯一真正的问题是你在这里生成的阵列是否真的会炸掉16MB的BSON限制。所以你可能需要对它进行一些细分,但它仍然比获取所有行并在客户端构建更好。
答案 1 :(得分:1)
您可以使用MongoDB Aggregation Framework。