gpt4 book ai didi

mongodb - 子数组上的MongoDb MapReduce

转载 作者:行者123 更新时间:2023-12-02 21:47:30 24 4
gpt4 key购买 nike

我已经在互联网上搜索了很长时间,但是找不到解决该问题的方法。尽管有很多Map reduce例子,但我感到困惑,因为我的文档具有一个对象数组的属性。

我很确定这对有经验的人来说应该很容易,但是我现在是菜鸟。

我有一个看起来像这样的文件

{
_id:guid,
clientId:guid,
reference:'abc123'
items:
[
{ _id:guid, category:'A', length:100, active:true },
{ _id:guid, category:'B', length:150, active:true },
{ _id:guid, category:'A', length:10, active:false },
{ _id:guid, category:'A', length:111, active:true },
]
}

我想产生这个输出

dateFromIdGuid(day) category countOfItems countOfActive sumOfLength

我想保持这种格式的数据以减少写操作的数量(每秒已经对该集合进行了1000次以上的写操作,并且还在不断增加)

这让我发疯,所以任何帮助将不胜感激。

谢谢。

最佳答案

如果您要讨论的是从GUID中提取时间戳并将其缩减为不连续的一天,那么MongoDB不会对您有太大帮助。您需要一个外部语言实现来支持该功能并实现一个外部mapReduce流程,例如使用Hadoop。

这使我想知道,是否我们实际上是在谈论GUID,或者您实际上是在说ObjectID,它将是文档的_id字段的默认值,除非已专门重写了其中的GUID。

即使不是这样,也可以通过在文档中添加某种“时间戳”字段并使用正确的BSON Date对象类型来帮助您,如下所示:

{
_id:guid,
"timestamp": ISODate("2014-05-27T00:00:00Z")
"clientId":guid,
"reference":'abc123'
"items":
[
{ _id:guid, category:'A', length:100, active:true },
{ _id:guid, category:'B', length:150, active:true },
{ _id:guid, category:'A', length:10, active:false },
{ _id:guid, category:'A', length:111, active:true },
]
}

这使您可以使用MongoDB聚合框架,因为它可以对这种类型的Date对象进行操作,以便将结果分解为离散的日期:

db.collection.aggregate([
{ "$unwind": "$items" },
{ "$group": {
"_id": {
"day": { "$dayOfYear": "$timestamp" },
"category": "$items.category"
},
"countOfItems": { "$sum": 1 },
"countOfActive": {
"$sum": {
"$cond": [
"$items.active",
1,
0
]
}
},
"sumOfLength": { "$sum": "$items.length" }
}}
])

这不仅以最快的方式为您提供了结果,而且MongoDB可以做到这一点,而且“时间戳”值还可以用于过滤日期范围内的查询,而这是您无法轻易从其他值中做到的。

此外,MongoDB mapReduce中还提供了JavaScript中提供的一种方法,该方法可让您从 ObejctId获取日期。但是,这比聚合框架要慢:

db.collection.mapReduce(
function() {
var date = this._id.getTimestamp();
items.forEach(function(item) {
var day =
"" + date.getFullyear() +
"" + ( date.getMonth() + 1 ) +
"" + date.getDate();
emit(
{
day: day,
category: item.category
},
{
countOfItems: 1,
countOfActive: ( item.active ) ? 1 : 0,
sumOfLength: item.length
}
);
});
},
function( key, values ) {
var reduced = {
countOfItems: 0,
countOfActive: 0,
sumOfLength: 0
};
values.forEach(function(value) {
for ( var k in value ) {
reduced[k] += value[k];
}
});
return reduced;
},
{
"out": { "inline": 1 }
}
)

基本上,映射器会分解数组并提供分组键,而精简器只是对映射器的值求和,这样做基本上是相同的。因此,即使您必须从GUID中提取内容,也可以在使用Hadoop时以Java等语言为您提供映射器和化简器的基本布局。

请查看 aggregatemapReduce手册页,以获取有关可以应用的选项的更多信息。

关于mongodb - 子数组上的MongoDb MapReduce,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23899351/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com