-1

次のSQLクエリを変換してmongodbを削減しようとしています:

select
    100.00 * sum(case 
            when p_type like 'PROMO%'
            then l_extendedprice*(1-l_discount) 
            else 0
            end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue
from 
    lineitem, 
    part
where 
    l_partkey = p_partkey
    and l_shipdate >= date '1995-09-01'
    and l_shipdate < date '1995-09-01' + interval '1' month;

上記のコレクションで使用したもの:

{
    "_id" : ObjectId("511b7d1b3daee1b1446ecdfe"),
    "l_linenumber" : 1,
    "l_quantity" : 17,
    "l_extendedprice" : 21168.23,
    "l_discount" : 0.04,
    "l_tax" : 0.02,
    "l_shipdate" : ISODate("1996-03-13T03:00:00Z"),
    "l_commitdate" : ISODate("1996-02-12T03:00:00Z"),
    "l_receiptdate" : ISODate("1996-03-22T03:00:00Z"),
    "l_comment" : "blithely regular ideas caj",
    "partsupp" : {
        "ps_availqty" : 6157,
        "ps_supplycost" : 719.17,
        "ps_comment" : "blithely ironic packages haggle quickly silent platelets",
        "ps_partkey" : {
            "p_partkey" : NumberLong(155190),
            "p_name" : "slate lavender tan lime lawn",
            "p_mfgr" : "Manufacturer#4",
            "p_brand" : "Brand#44",
            "p_type" : "PROMO BRUSHED NICKEL"
        }
    }
}

この mapreduce:

 db.runCommand({
    mapreduce: "lineitem",
    query: {
        l_shipdate: {'$gte': new Date("Sept 01, 1995"), '$lt': new Date("Oct 01, 1995")}
    },
    map: function() {
        var data = {promo_revenue:0, divisor:0, dividendo: 0 };
        var pattern = /PROMO$/;
        var discount = 1 - this.l_discount;
        var revenue = this.l_extendedprice * discount;

            if(this.partsupp.ps_partkey.p_type.match(pattern)!= null){
                data.divisor = revenue;
            }else{
                data.divisor = 0;
            }

            data.dividendo = revenue;
            emit("PROMO_REVENUE", data);
    },
    reduce: function(key, values) {
        var data = {promo_revenue:0, divisor:0, dividendo: 0 };
        for (var i = 0; i < values.length; i++) {
            data.divisor += values[i].divisor;
            data.dividendo += values[i].dividendo;
        }

        var resultado = data.divisor / data.dividendo;
        data.promo_revenue = 100.00 * resultado;

        return data;
    },
    out: 'query014'
 });

私はこの答えを取得します:

{ "_id" : "PROMO_REVENUE", "value" : { "promo_revenue" : 0, "divisor" : 0, "dividendo" : 2761949328.227077 } }

問題:

私が適用した正規表現は正しいですか?除数が常にゼロになるのは奇妙です。そして、除数が常にゼロである場合にのみ、答えは正しいかどうか?

ありがとう

4

1 に答える 1

1

LIKE 'PROMO%'は正規表現ではありませんが、%「0 個以上の任意の文字」のワイルドカードです。同等の正規表現はおそらく/PROMO.*/. /PROMO$/は「PROMO で終わる」という意味です。

于 2013-02-20T01:24:01.340 に答える