Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

242
Vistas
Get count of product attributes from MongoDB

I have a mongo collection of products with attributes:

{
  "_id" : ObjectId("5888a2860c001d31a1089958"),
  "product_id" : "107",
  "store_id" : 0,
  "attributes" : [{
      "key" : "m",
      "value" : 21,
      "label" : "Mothercare"
    }, {
      "key" : "sp",
      "value" : 10.0,
      "label" : 10.0
    }, {
      "key" : "pr",
      "value" : 2,
      "label" : "150-300"
    }, {
      "key" : "c",
      "value" : 59,
      "label" : "Category 1"
    }, {
      "key" : "c",
      "value" : 86,
      "label" : "Category 2"
    }, {
      "key" : "c",
      "value" : 134,
      "label" : "Category 3"
    }, {
      "key" : "c",
      "value" : 1013,
      "label" : "Category 4"
    }, {
      "key" : "c",
      "value" : 1063,
      "label" : "Category 5"
    }, {
      "key" : "c",
      "value" : 1073,
      "label" : "Category 6"
    }, {
      "key" : "13",
      "value" : 270,
      "label" : "Brown"
    }, {
      "key" : "18",
      "value" : 125,
      "label" : "Girl"
    }, {
      "key" : "19",
      "value" : 298,
      "label" : "0-3 month"
    }, {
      "key" : "19",
      "value" : 299,
      "label" : "3-6 month"
    }, {
      "key" : "19",
      "value" : 300,
      "label" : "6-9 month"
    }, {
      "key" : "19",
      "value" : 301,
      "label" : "9-12 month"
    }]
}

I need to find fast way for get count of all attributes in collection. I have tried to use MapReduce:

function map() {
    var max = this.attributes.length;
    var key = {};

    for (var i = 0; i < max; i++) {
        key = {
            key: this.attributes[i]['key'],
            value: this.attributes[i]['value'],
        }

        emit(key, {count: 1}); 
    }
}
function reduce(key, values) {
    var sum = 0;
    values.forEach(function(value) {
        sum += value['count'];
    });
    return {count: sum};
};

But it very slow:

timeMillis=2420  
counts={ "input" : 18963, "emit" : 221232, "reduce" : 7341, "output" : 1289 }

How can I find the quantity of all attributes faster? I need it for product filter. Maybe I must use other collection structure?

I not need to find total count of attributes, I need to find count of each attribute, for example:
{ "key" : "c", "value" : 59 } has 2345 products
{ "key" : "m", "value" : 21 } has 258 products

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Running the following pipeline will give you the desired result:

db.collection.aggregate([
    { "$unwind": "$attributes" },
    {
        "$group": {
            "_id": {
                "key": "$attributes.key",
                "value": "$attributes.value"
            },
            "counts": { "$sum": 1 }
        }
    }
])

For a more efficient query, use the aggregation framework. Consider running a pipeline with $project to get the number of attributes per document using the $size operator on the attributes array and then a final $group pipeline where you can specify an _id value of null to calculate accumulated values for all the input documents as a whole and calculate the total counts using $sum as follows:

db.collection.aggregate([
    {
        "$project": {
            "counts": {
                "$size": "$attributes"
            }
        }       
    },
    {
        "$group": {
            "_id": null,
            "counts": { "$sum": "$counts" }
        }
    }
])

The above will return the total number of attributes of ALL products in a collection.


If you want to use the count of the attributes to filter a product, then consider using the $redact pipeline as:

var attributeCount = 12; // for example
db.collection.aggregate([
    {
        "$redact": {
            "$cond": [
                { "$eq": [ { "$size": "$attributes" }, attributeCount ] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }       
    }
])

This is equivalent to a combination of a $project and $match pipeline albeit you don't have to specify all the fields in the $project pipeline, as in the following:

db.collection.aggregate([
    {
        "$project": {
            "product_id": 1,
            "store_id": 1,
            "$attributes": 1,
            "counts": {
                "$size": "$attributes"
            }
        }       
    },
    { "$match": { "counts": { "$gte": attributeCount } } }
])

over 4 years ago · Santiago Trujillo Denunciar

0

To get total count of attributes by key value pair can try this query.

db.collectionName.aggregate([
    {$unwind:{"$attributes"}}
    {$group: {
            _id: {"key": "$attributes.key","value": "$attributes.value"},
            count: { $sum: 1 }
        }
    },
    {$project:{
        key:"$_id.key",
        value:"$_id.value",
        count:1
       }
    }
])
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda