web-dev-qa-db-fra.com

groupe dans mongo à l'exclusion des valeurs nulles

J'ai une requête mongo qui effectue l'opération de groupe sur les documents.

J'ai presque obtenu les résultats attendus, sauf que je veux affiner les résultats sans valeurs vides ou nulles.

Actuellement, ma requête ressemble à ceci:

db.productMetadata.aggregate([{$group:{"_id":{"color":"$productAttribute.colour","gender":"$productAttribute.gender"},"count" : {$sum : 1}}}]);

Et les résultats ressemblent à ceci:

{ "_id" : { "color" : "BLUE", "gender" : "MEN" }, "count" : 1 }
{ "_id" : {  }, "count" : 4 }
{ "_id" : { "color" : "NA", "gender" : "WOMEN" }, "count" : 1 }
{ "_id" : { "color" : "BLACK", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "BROWN", "gender" : "WOMEN" }, "count" : 1 }
{ "_id" : { "gender" : "MEN" }, "count" : 2 }
{ "_id" : { "color" : "BEIGE", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "BROWN", "gender" : "MEN" }, "count" : 1 }

Je souhaite supprimer les lignes si l'une des valeurs de regroupement par champ est vide ou nulle dans les données réelles de la base de données.

Les résultats exceptés devraient ressembler à ceci:

{ "_id" : { "color" : "BLUE", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "NA", "gender" : "WOMEN" }, "count" : 1 }
{ "_id" : { "color" : "BLACK", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "BROWN", "gender" : "WOMEN" }, "count" : 1 }
{ "_id" : { "color" : "BEIGE", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "BROWN", "gender" : "MEN" }, "count" : 1 }
17
starkk92

Vous avez besoin d'un supplément $match étape de pipeline qui filtrera les documents entrants en fonction du champ incorporé "$productAttribute.colour" existant et non nul:

    db.productMetadata.aggregate([
    { 
        "$match": {
            "productAttribute.colour": { 
                "$exists": true, 
                "$ne": null 
            }
        }    
    },
    { 
        "$group": {
            "_id": {
                "color": "$productAttribute.colour",
                "gender": "$productAttribute.gender"
            },
            "count": { 
                "$sum": 1 
            }
        }   
    }        
]);
28
chridam

Vous devriez peut-être utiliser $ match: {'color': {$ exist: true}} avant $ group operation. Avec un index clairsemé, cela fonctionnera assez rapidement. Et ne stockez pas du tout les champs "null" dans les collections, cela réduira la taille de la base de données et augmentera la vitesse de recherche pour les index épars (moins de documents dans l'index -> plus de vitesse)

0
Sergey Mazur

cet exemple comprend deux collections différentes. Pour cela, nous utilisons la fonction d'agrégation. J'utilise également Mongoose

  1. Je rejoins le cusmtomfield avec des étiquettes personnalisées avec $ lookup
  2. Flat the array with $ unwind
  3. $ match pour exclure le nom qui a INACTIVE dans le texte (j'utilise REGEX)
  4. $ project pour renommer les champs pour qu'ils s'affichent correctement sur le client

    . async getAllMasterDataCustomFields (req) {

        let response = {};
        try {
    
          response = await customfieldsModel.aggregate([
            {
              $lookup: {
                from: 'customfieldlabels',
                localField: 'cfId',
                foreignField: 'cfId',
                as: 'info'
              }
            },
            { '$unwind': { 'path': '$info', 'preserveNullAndEmptyArrays': true } },
            { '$match': { 'childs.name': { $not: /INACTIVE/ }}},
            {
              $project: {
                'cfId': 1,
                'label': '$info.label',
                'type': '$info.type',
                'childs': 1
              }
            }]).exec();
    
        } catch (e) {
          logger.log('error', `Error while getting response ${e.meesage}`);
        }
    
        return response;
      }
    

    .

0