2015-07-30 1 views
1

Prenant l'exemple de la collection comme:agrégation MongoDB comme la recherche à facettes

db.products.insert([ 
    {"product_name": "Product 1", "filters": [{"name": "brand", "value": "Brand 1"}, {"name": "color", "value": "Color 1"}]}, 
    {"product_name": "Product 2", "filters": [{"name": "brand", "value": "Brand 2"}, {"name": "color", "value": "Color 2"}]}, 
    {"product_name": "Product 3", "filters": [{"name": "brand", "value": "Brand 1"}, {"name": "color", "value": "Color 2"}]}, 
    {"product_name": "Product 4", "filters": [{"name": "brand", "value": "Brand 3"}, {"name": "color", "value": "Color 1"}]}, 
    {"product_name": "Product 5", "filters": [{"name": "brand", "value": "Brand 3"}, {"name": "color", "value": "Color 3"}]} 
]) 

Si l'on doit regrouper sur la liste des dictionnaires et obtenir les comptes regroupés pour chacun d'eux, comme ce qui suit:

(marque)
marque 1: 2
marque 2: 1
marque 3: 2

(couleur)
Couleur 1: 2
Couleur 2: 2
Couleur 3: 3

Quelle pourrait être la façon pertinente pour obtenir?

+0

double possible de [MongoDB requêtes d'optimisation] (http://stackoverflow.com/questions/27837150/ mongodb-queries-optimization) –

+0

@BlakesSeven: Probablement pas. Le lien que vous avez fourni est très spécifique à mongoose –

Répondre

2

Utilisez cette agrégation comme ci-dessous:

db.products.aggregate({ 
    "$unwind": "$filters" 
}, { 
    "$group": { 
    "_id": { 
     "value": "$filters.value", 
     "name": "$filters.name" 
    }, 
    "count": { 
     "$sum": 1 
    } 
    } 
}, { 
    "$group": { 
    "_id": "$_id.name", 
    "data": { 
     "$push": { 
     "value": "$_id.value", 
     "totalCount": "$count" 
     } 
    } 
    } 
}).pretty() 
+1

Cela fonctionne parfaitement selon ma requête originale! Toute idée de comment obtenir multi-select comme facettage avec les mêmes données ci-dessus comme dans https://wiki.apache.org/solr/SimpleFacetParameters#Multi-Select_Faceting_and_LocalParams –

0

Vous devez unwind vos données pour obtenir un jeu de données plat et par les valeurs de filtre.

db.products.aggregate(
{ 
    $unwind: "$filters", 
}, { 
    $group: { 
     _id: "$filters.value", 
     product_names: { $push: "$product_name" } , 
     count: { $sum: 1 } 
    } 
}); 

Retours

{ 
    "result" : [ 
     { 
      "_id" : "Color 3", 
      "product_names" : [ 
       "Product 5" 
      ], 
      "count" : 1 
     }, 
     { 
      "_id" : "Brand 3", 
      "product_names" : [ 
       "Product 4", 
       "Product 5" 
      ], 
      "count" : 2 
     }, 
     { 
      "_id" : "Color 2", 
      "product_names" : [ 
       "Product 2", 
       "Product 3" 
      ], 
      "count" : 2 
     }, 
     { 
      "_id" : "Color 1", 
      "product_names" : [ 
       "Product 1", 
       "Product 4" 
      ], 
      "count" : 2 
     }, 
     { 
      "_id" : "Brand 2", 
      "product_names" : [ 
       "Product 2" 
      ], 
      "count" : 1 
     }, 
     { 
      "_id" : "Brand 1", 
      "product_names" : [ 
       "Product 1", 
       "Product 3" 
      ], 
      "count" : 2 
     } 
    ], 
    "ok" : 1 
}