Home > Back-end >  Bucketing based on whether a field exists or not
Bucketing based on whether a field exists or not

Time:04-23

I have data that looks like this:

{ fname: "bob", age: 33, description: "brown eyes"}
{ fname: "sally", age: 20, description: "tall"}
{ fname: "jim", age: 48 }

I'm trying to, in one query, get results that look something like this:

{
   hasDescription: ["bob", "sally"],
   noDescription: ["jim"]
}

I've been playing around with $bucketAuto with something like this:

{
  groupBy: { "$cond": [{ "$eq": [ "description", null ] }, true, false ] },
  buckets: 2,
}

but am not having any success. Any guidance would be appreciated!

CodePudding user response:

Query

  • group with expression on group, to make 2 groups, one that have description and one that doesnt (instead of a field to create the group, we create 2 groups based on a condtion)
  • the other 3 stages is to fix the structure to be like the expected output

*i don't think you need bucket, bucket is for range of values
*instead of the bellow facet could be used also, but facet is like running the aggregation 1 time per field so its slower

Playmongo (mouse to the end of each stage => see in/out of each stage)

aggregate(
[{"$group": 
   {"_id": 
     {"$cond": 
       [{"$ne": [{"$type": "$description"}, "missing"]}, "hasDescription",
        "noDescription"]},
    "names": {"$push": "$fname"}}},
 {"$replaceRoot": 
   {"newRoot": 
     {"$cond": 
       [{"$eq": ["$_id", "noDescription"]}, {"noDescription": "$names"},
         {"hasDescription": "$names"}]}}},
 {"$group": {"_id": null, "docs": {"$mergeObjects": "$$ROOT"}}},
 {"$replaceRoot": {"newRoot": "$docs"}}])
  • Related