草庐IT

MongoDB 映射减少 : Not working as expected for more than 1000 records

coder 2023-10-31 原文

我编写了一个 mapreduce 函数,其中以下列格式发出记录

{userid:<xyz>, {event:adduser, count:1}}
{userid:<xyz>, {event:login, count:1}}
{userid:<xyz>, {event:login, count:1}}
{userid:<abc>, {event:adduser, count:1}}

其中 userid 是键,其余是该键的值。 在 MapReduce 函数之后,我想得到以下格式的结果

{userid:<xyz>,{events: [{adduser:1},{login:2}], allEventCount:3}}

为了实现这一点,我编写了以下 reduce 函数 我知道这可以通过 group by .. 在聚合框架和 mapreduce 中实现,但我们需要针对复杂场景的类似功能。所以,我正在采用这种方法。

var reducefn = function(key,values){
var result = {allEventCount:0, events:[]};
values.forEach(function(value){
    var notfound=true;
    for(var n = 0; n < result.events.length; n++){
        eventObj = result.events[n];
        for(ev in eventObj){
            if(ev==value.event){
                result.events[n][ev] += value.allEventCount;
                notfound=false;
                break;
            }
        }
    }
    if(notfound==true){ 
        var newEvent={}
        newEvent[value.event]=1; 
        result.events.push(newEvent);
    }
    result.allEventCount += value.allEventCount;
});
return result;

这运行完美,当我运行 1000 条记录时,当有 3k 或 10k 条记录时,我得到的结果是这样的

{ "_id" : {...}, "value" :{"allEventCount" :30, "events" :[ { "undefined" : 1},
{"adduser" : 1 }, {"remove" : 3 }, {"training" : 1 }, {"adminlogin" : 1 }, 
{"downgrade" : 2 } ]} }

无法理解此 undefined 的来源,而且各个事件的总和小于 allEventCount。集合中的所有文档都有非空字段 event,所以没有未定义的机会。

Mongo 数据库版本 -- 2.2.1 环境 -- 本地机器,无分片。

在reduce函数中,为什么这个操作会失败result.events[n][ev] += value.allEventCount; 当类似的操作result.allEventCount += value.allEventCount ; 通过?

johnyHK 建议的更正答案

归约函数:

    var reducefn = function(key,values){
    var result = {totEvents:0, event:[]};
    values.forEach(function(value){
        value.event.forEach(function(eventElem){
            var notfound=true;
            for(var n = 0; n < result.event.length; n++){
                eventObj = result.event[n];
                for(ev in eventObj){
                for(evv in eventElem){
                    if(ev==evv){
                        result.event[n][ev] += eventElem[evv];
                        notfound=false;
                        break;
                    }
                }}
            }
            if(notfound==true){ 
                result.event.push(eventElem);
            }
        });
        result.totEvents += value.totEvents;
    });
    return result;
}

最佳答案

您从 map 函数发出的对象的形状必须与从您的 reduce 函数返回的对象相同,因为当处理大量文档时,reduce 的结果可以反馈到 reduce 中(如本例)。

所以你需要改变你的 emit 来发出这样的文档:

{userid:<xyz>, {events:[{adduser: 1}], allEventCount:1}}
{userid:<xyz>, {events:[{login: 1}], allEventCount:1}}

然后相应地更新您的 reduce 函数。

关于MongoDB 映射减少 : Not working as expected for more than 1000 records,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14138344/

有关MongoDB 映射减少 : Not working as expected for more than 1000 records的更多相关文章

  1. ruby-on-rails - Rails 5 Active Record 记录无效错误 - 2

    我有两个Rails模型,即Invoice和Invoice_details。一个Invoice_details属于Invoice,一个Invoice有多个Invoice_details。我无法使用accepts_nested_attributes_forinInvoice通过Invoice模型保存Invoice_details。我收到以下错误:(0.2ms)BEGIN(0.2ms)ROLLBACKCompleted422UnprocessableEntityin25ms(ActiveRecord:4.0ms)ActiveRecord::RecordInvalid(Validationfa

  2. ruby-on-rails - 只有当不是 nil 时才执行映射? - 2

    如果names为nil,则以下中断。我怎样才能让这个map只有在它不是nil时才执行?self.topics=names.split(",").mapdo|n|Topic.where(name:n.strip).first_or_create!end 最佳答案 其他几个选项:选项1(在其上执行map时检查split的结果):names_list=names.try(:split,",")self.topics=names_list.mapdo|n|Topic.where(name:n.strip).first_or_create!e

  3. ruby-on-rails - Ruby 数组等效于 active record.where(criteria) - 2

    这可能是一段很长的时间,但如果存在的话会让生活变得更轻松一些。无论如何,这都是场景。我有一个散列数组,其中一个键的值是另一个散列.......是的,我知道。这里有一个更好的解释:@myArrayOfStuff[0]@myArrayOfStuff[0]["single-key"]@myArrayOfStuff[0]["single-key"]["object-identifier"]第一个返回一个散列。第二个将返回一个对象(在我的例子中称为页面,但示例使用不同的名称)第三个返回我作为对象标识符引用的任何变量。足够简单。我想做的是选择另一个对象标识符值不为零或大于x的数组。类似于activ

  4. Ruby:映射和注入(inject)之间的区别 - 2

    在此处阅读有关SO的各种解释,它们是这样描述的:map:Themapmethodtakesanenumerableobjectandablock,andrunstheblockforeachelement注入(inject):Injecttakesavalueandablock,anditrunsthatblockonceforeachelementofthelist.希望你明白为什么我觉得它们表面上看起来很相似。我什么时候会选择一个而不是另一个,它们之间有什么明显的区别吗? 最佳答案 如果您认为inject也别名为reduce,这

  5. ruby - 减少数组时使用 Hash.new 作为初始值 - 2

    我有一个这样的数组[1,1,2,3,3,3,4,5,5]我想计算每个数字出现的次数,我正在尝试这样做[1,1,2,3,3,3,4,5,5].reduce(Hash.new(0)){|hash,number|hash[number]+=1}问题是当我尝试运行它时出现以下错误NoMethodError:undefinedmethod`[]='for1:Fixnumfrom(irb):6:in`blockinirb_binding'from(irb):6:in`each'from(irb):6:in`reduce'from(irb):6我能像这样设置初始值吗,还是我弄错了?

  6. ruby-on-rails - my_object.save(false) 并没有真正跳过我的 Active Record 验证 - 2

    所以我一直在努力解决我一直遇到的这个错误,我终于找到了导致它的原因。我一直觉得,当我调用@my_model.save(false)我会跳过我的ActiveRecord验证。事实证明这是部分正确的。我的对象正在保存到数据库中DESPITE我的ActiveRecord验证。我的问题存在是因为我的一个验证在验证过程中修改了一个子模型(这是一个24小时位置的调度应用程序,因此当午餐被保存时,我对照他们保存的那天和第二天检查它们以及确保用户不是指“凌晨2点”表示要上夜类。我的问题是:有没有办法真正跳过我的验证并直接移动到数据库?这是正常的ActiveRecord行为还是我应该更深入地研究我的验证

  7. ruby - 扩展 ActiveSupport::Notifications.subscribe, instantiation.active_record 钩子(Hook) - 2

    我正在探索ActiveSupport::Notifications,并且想要更多关于'instantiation.active_record'的信息,而不仅仅是:record_count和:类名[1].例如,ActiveSupport::Notifications.subscribe/instantiation.active_record/do|*args|args.status#DatabaseorActiveRecordreturnstatusargs.result#Theactualresultsetreturnedargs.etc..#AnyotherinfoIcancolle

  8. ruby-on-rails - Ruby on Rails URL 中的资源映射(RESTful API) - 2

    我很难给出正确的答案,所以我会在这里征求我的问题。我正在研究RESTFulAPI。自然地,我有多种资源,其中一些由父子关系组成,一些是独立资源。我有点困难的地方是弄清楚如何让那些将根据我的API构建客户端的人更容易。情况是这样的。假设我有一个“街道”资源。每条街道都有多个住宅。SoStreet:has_manytoHomes和Homes:belongs_toStreet。如果用户想要在特定的home资源上请求HTTPGET,以下应该可行:http://mymap/streets/5/homes/10这允许用户获取ID为10的房屋的信息。直截了当。我的问题是,我授予用户访问权限是否违反了

  9. ruby-on-rails - ruby rails : Find records without Sorting - 2

    我需要按照作为搜索参数传入的准确顺序查找记录。例如,我有一个字符串:item_list="23,12,54,45"通过以下查询,我按“item_list”的asc顺序获取记录-“12,23,45,54”。Inventory.find(item_list.split(","))如何修改上述查询,使其以与“item_list”相同的顺序返回记录。谢谢。 最佳答案 试试这个,虽然它可能只适用于MySQL:Inventory.where("idIN(#{item_list})").order("find_in_set(id,'#{item_

  10. ruby - 按组大小排列的 Active Record 顺序 - 2

    我有一个正在使用group_by的事件记录查询@foo=Foo.group_by(&:relation)然后在我正在使用的View中@foo.eachdo|group,values|groupxhasvalues.countelementsend有没有一种方法可以根据每组的数量对这些进行排序? 最佳答案 group_by不是ActiveRecord方法,group是。group_by是一个枚举器方法。怎么样@foo=Foo.group('relation').order('count_idasc').count('id')取自"Or

随机推荐