2

Well im trying translate this sql query to map reduce

select
    o_orderpriority, 
    count(*) as order_count
from 
    orders
where 
    o_orderdate >= date '1993-07-01'
    and o_orderdate < date '1993-07-01' + interval '3' month
    and exists (
        select 
        *
        from 
        lineitem
        where 
        l_orderkey = o_orderkey
        and l_commitdate < l_receiptdate
    )
group by 
    o_orderpriority
order by 
    o_orderpriority;

Ive tried the following map reduce function

    db.runCommand({
    mapreduce: "orders",
    query: {
        o_orderdate: {'$gte': new Date("July 01, 1993")},
        o_orderdate: {'$lt': new Date("Oct 01, 1993")}
    },
    map: function Map() {
            for(var i in this.o_lineitem) {
                if( this.o_lineitem[i].l_commitdate < this.o_lineitem[i].l_receiptdate) {
                    var o_orderpriority = this.o_lineitem[i].o_orderpriority;
                    emit( o_orderpriority, {count: 1} );
                }
            }
        },
    reduce: function(key, values) {
                var count= 0;
                for (var i = 0; i < values.length; i++) {
                    count+= values[i];
                }
                return count;
            },
    out: 'query004'
});

when a i run i get the follow alert

Sat Aug 11 20:44:32 SyntaxError: missing ) after condition (shell):9

For me there's no ) missing, is it there?

I did the corrections pointed by @Stenie, but now a i have the follow problem

{
        "assertion" : "value too large to reduce",
        "assertionCode" : 13070,
        "errmsg" : "db assertion failure",
        "ok" : 0
}
6
  • you are missing a '.' on line 9: if( this.o_lineitem[i].l_commitdate < this.o_lineitem[i]l_receiptdate) <-- there should be a . after the last ] before l_receiptdate Commented Aug 12, 2012 at 5:58
  • @AsyaKamsky i put the point but the problem continues: Sun Aug 12 09:03:31 SyntaxError: missing ) after argument list (shell):10 Commented Aug 12, 2012 at 12:05
  • 1
    @ulima69: line 10 has emit(this.o_lineitem[i].o_orderpriority, count_order: 1); but should be emit(this.o_lineitem[i].o_orderpriority, count_order);. Commented Aug 12, 2012 at 13:13
  • 1
    @ulima69: oops, should have read the reduce() .. so think you actually want: emit(this.o_lineitem[i].o_orderpriority, { count_order: 1 }). Note that your reduce is using order_count and doesn't appear to be writing any results into the ret value. Commented Aug 12, 2012 at 14:09
  • 1
    just use emit(this.o_lineitem[i].o_orderpriority, 1) - you don't need to emit a document. Commented Aug 13, 2012 at 3:59

1 Answer 1

3

The problem is your emit and your reduce function do not return the same thing.

Your map function emits the value:

{count: 1}

That means your reduce must return the same format.

You are returning a simple value in your reduce:

return count;

You can change your emit to just emit 1 instead of JSON document and then you don't have to change your reduce, otherwise change your reduce to return a JSON document {count: X} where X is the computed count.

FYI, the reason this is causing the error "value too large to reduce" is that once you mix your types like this, the '+' operator starts concatenating your values rather than adding them and eventually it gets too large. To see how you could debug this I recommend the Troubleshooting MapReduce page

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.