Reputation: 744
My document structure looks like this
{
title : 'a product',
price : 10
}
What i would like to do is a dynamic price range facet which would look like this
[
{
facet : '0-30',
count : 5
},
{
facet : '30-100',
count : 40
}
]
Obviously there would be a fixed interval, for example 50. I used to have ElasticSearch do this for me using the histogram function but i can't get it to work in mongo. I suppose, one could do a map reduce to get it done, but i wonder if there is a way to added to my aggregation pipeline.
Upvotes: 3
Views: 1373
Reputation: 103445
You could try an aggregation pipeline where you can project the facet
field using the $cond
operator. To demonstrate this, suppose you have a collection with the following documents:
db.collection.insert([
{ "title" : "Product STU", "price" : 10 },
{ "title" : "Product XYZ", "price" : 50 },
{ "title" : "Product PCT", "price" : 14 },
{ "title" : "Product DEF", "price" : 89 },
{ "title" : "Product DYQ", "price" : 34 },
{ "title" : "Product ABC", "price" : 40 },
{ "title" : "Product JKL", "price" : 50 },
{ "title" : "Product PQR", "price" : 75 },
{ "title" : "Product MNO", "price" : 81 },
{ "title" : "Product VWN", "price" : 5 },
{ "title" : "Product KLM", "price" : 63 }
]);
The aggregation pipeline that will achieve the desired result is as follows:
db.collection.aggregate([
{
"$match": {
"price": { "$lte": 100, "$gte": 0 }
}
},
{
"$project": {
"title": 1,
"price": 1,
"_id": 0,
"facet": {
"$cond": [ { "$gte": [ "$price", 30 ] }, "30-100", "0-30" ]
}
}
},
{
"$group": {
"_id": "$facet",
"count": {
"$sum": 1
}
}
},
{
"$project": {
"facet": "$_id",
"_id": 0,
"count": 1
}
}
])
Output:
/* 1 */
{
"result" : [
{
"count" : 8,
"facet" : "30-100"
},
{
"count" : 3,
"facet" : "0-30"
}
],
"ok" : 1
}
Upvotes: 2