2017-10-18 19 views
0

désolé pour mon anglais ..Comment comparer les champs en AggregateFunction

je dois comparer les user'param (MonthYear/6characters) avec les TxtDtVts sur le terrain (une date avec 7 ou 8 caractères) Si elles correspondent, il doit retourner les champs « CodeTva » et « TauxTVA » par le mois désiré

ci-dessous est ma collection « billets »:

{ 
    "_id" : ObjectId("59e66bdda00472964e6a950b"), 
    "Pharma" : "HEA00001", 
    "TxtDtVts" : 2012016, // Or 22012016 (7 or 8 characts) 
    "TxtHrsVts" : 842, 
    "NumVts" : 845613, 
    "NumEmp" : 19, 
    "NumPoste" : 127, 
    "PVHT" : 1.0575, 
    "CodeTva" : 4, 
    "TauxTVA" : 2.1, 
    "PVTTC" : 1.08, 
} 

Voici mon point final et ma fonction d'agrégation:

secureRoutes.route('/ticketTVA/month/:MonthYear') // Example 012016 

.get(function(req, res){ 
    var mois= req.params.month; 

    Ticket.aggregate([ 

    {$project:{ 
     TxtDtVts:1, 

     Correspondance: { 
      $let: { 
       vars: { 
        monthSubstring: { $substr: [ "$TxtDtVts", 0, -1 ] }, 
        moisReq:{$substr: ["$mois",0,-1]}, 

       }, 
       in: { $cmp: [ "$$monthSubstring", "$$moisReq" ] } 
      } 
     } 
    }}, 

     ],function (err, result) { 
     if (err) { 
      console.log(err); 
      return; 
     } 
     console.log(result); 
     res.json(result); 
    }); 
}) 

J'ai essayé d'utiliser $ substr pour convertir des données en chaîne, les sauvegarder dans vars et utiliser $ cmp pour les comparer.

Si je fais ça (sans match avant), j'ai une erreur: errmsg: 'aggregation result exceeds maximum document size (16MB) Plus, il est une mauvaise façon parce que le changement de longueur TxtDtVts (1.012.016 OU 10012016) .. Comment comparer ces 2 données et si elle correspond , retourne moi "CodeTva" et "TauxTVA"?

Nous vous remercions à l'avance

+0

TxtDtVts semble être un entier, pas une chaîne ou une date. Pourriez-vous expliquer un peu plus comment l'entrée de 6 caractères devrait correspondre à la sortie de 7 ou 8 caractères? –

+0

Les 6 caractères d'entrée représentent MMYEAR. – Jbee

+0

Donc l'entrée est une chaîne, MMYYYY, et vous comparez cela à un entier de 7 ou 8 chiffres qui est structuré comment? On dirait que MDDYYYY ou MMDDYYYY? –

Répondre

0

Essayez ceci sur la taille: Faites votre entrée un entier, pas une chaîne. Il est facile de prendre vos commentaires et de le faire. Puis:

db.foo.aggregate([ 
    { $addFields: { 
    "rc": {$eq: [{$divide:[{ "$subtract": [ "$date", input ] },1000000]}, 
       {$trunc: {$divide:[{ "$subtract": [ "$date", input ] },1000000]}} ]} 
    }} 
    ,{ $match: {"rc":true}} 
       ]); 

L'idée est de prendre une date comme 8022013 (8 février 2013) ou 25121970 (25 décembre 1970) et soustraire de la composante MMAAAA. Donc, une entrée de 22013 (la version int de la chaîne "022013", notez comment la valeur zéro) diminue de 8000000. La division par 1000000 sur une base virgule flottante et entière donne le même nombre (8). Si la date du DB était 8032013, le diff est 8010000. Cela donne 8 et 8.01 qui ne sont pas égaux.

+0

Je vais essayer d'utiliser $ addFields mais s'il n'y a pas $ pipe dans ma fonction d'agrégat, j'ai toujours la même erreur: errmsg: 'le résultat de l'agrégation dépasse la taille maximale du document (16MB)'. deux valeurs dans $ match pipe? – Jbee

+0

J'ai ajouté l'opérateur $ match pour capturer uniquement les dates qui correspondent. Il n'y a pas de construction intermédiaire d'un doc impliqué ici; vous ne devriez pas tomber dans des limites de 16 Mo. –

+0

J'ai trouvé une solution: var mois = req.params.mois; jrsDuMois = []; var i = 1; pour (; i <= 31; i ++) – Jbee

0

J'ai trouvé une solution

jrsDuMois= []; 
var i = 1; 
for (; i <= 31; i++) { 
jrsDuMois.push(parseInt(i+""+mois)); 
} 

Et je compare le champ TxtDtVts avec mon tableau "jrsDuMois":

{ "$match": { 
     "TxtDtVts": { "$in": jrsDuMois }, 
     }},