2012-08-14 3 views
1

Je traduis la requête sql ci-dessous en une requête de réduction de carte pour mongodb.Comment écriture existe clause sql dans MongoDB?

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; 

Et la carte suivante réduire la requête:

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' 
}); 

Regardez que o_linetem est un tableau intégré dans la collecte des commandes.

Eh bien, les résultats sont les suivants:

Dans SQL:

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

l'autre côté résultat 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 } 

ce qui se passe? Qu'est-ce que j'ai fait de mal dans la carte réduire?

+0

$ sorties? Je ne suis pas tout à fait sûr de ce que fait votre SQL, mais je vais essayer de le comprendre. – ranman

Répondre

1

Vous émettez chaque priorité plusieurs fois s'il y a plusieurs lignes dans l'ordre qui n'ont pas atteint la date de validation attendue.

Vous ne le faites pas dans votre instruction SQL - clause exists vérifie uniquement qu'il existe au moins un élément de ligne qui n'a pas respecté la date de validation.

Si vous souhaitez faire l'équivalent dans map/reduce, vous devez ajouter une instruction return; après avoir émis avec succès pour chaque document de commande.

+0

vous pouvez également simplifier le tout en ajoutant exister à votre requête pour commencer, auquel cas votre carte est juste une ligne unique (this.o_orderpriority, 1); –

+0

en effet j'émettais les mêmes commandes plusieurs fois. Merci beaucoup une fois de plus @ asya-kamsky – ulima69