1

我将下面的 sql 查询翻译成 mongodb 的 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;

以及以下 map reduce 查询:

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) {
                        emit( this.o_orderpriority, 1 );
                    }
                }

        },
    reduce: function(key, values) {
                var count = 0;
                for (var i = 0; i < values.length; i++) {
                    count += values[i];
                }
                return count;
            },
    out: 'query004'
});

看看 o_linetem 是订单集合中的嵌入式数组。

结果是:

在 SQL 中:

1-URGENT            10594
2-HIGH          10476
3-MEDIUM            10410
4-NOT SPECIFIED 10556
5-LOW           10487

在另一边的 MongoDB 结果中:

{ "_id" : "1-URGENT", "value" : 29215 }
{ "_id" : "2-HIGH", "value" : 29020 }
{ "_id" : "3-MEDIUM", "value" : 28616 }
{ "_id" : "4-NOT SPECIFIED", "value" : 29253 }
{ "_id" : "5-LOW", "value" : 28765 }

发生什么事?我在地图减少中做错了什么?

4

1 回答 1

1

如果订单中有多个订单项不符合预期的提交日期,则您将多次发出每个订单优先级。

您没有在 SQL 语句中这样做 - exists 子句仅检查至少有一个行项目不符合提交日期。

如果你想在 map/reduce 中做同样的事情,那么你应该return;在为每个订单文档成功发出之后添加一个语句。

于 2012-08-14T20:30:52.930 回答