Wachburn
Wachburn

Reputation: 2939

Get distinct values of child array as additional property

For example we have a collection with documents like this:

{
    "_id" : "1",
    "Category" : "11",
    "Type" : 1,
    "Active" : true,
    "IsValid" : null,
     .
     .
     .
     .
    "AllTags": ["Product", "Product", "Product", "Response", "Comment", "Response"]
}

How can we output documents exactly like these, but which will contain additional field with distinct Tags: ["Product", "Response", "Comment"]. So resulting document will look like this:

{
    "_id" : "1",
    "Category" : "11",
    "Type" : 1,
    "Active" : true,
    "IsValid" : null,
     .
     .
     .
     .
    "AllTags": ["Product", "Product", "Product", "Response", "Comment", "Response"],
    "Tags": ["Product", "Response", "Comment"] //property calculated from AllTags
}

I'm trying to add stage $AddFields

{ "$addFields" : { "Tags" : {"$reduce": { "input": "$AllTags", initialValue: [], in: {  
        $cond: { if: { "$$this": {$nin: ["$$value"]} } , then:  { $concatArrays : ["$$value", ["$$this"]] }, else: ?  }            
    } } } } }

But it gives this error: "Invalid $addFields :: caused by :: Unrecognized expression '$$this'", and I don't know what to put inside else of $cond op.

Upvotes: 1

Views: 415

Answers (1)

turivishal
turivishal

Reputation: 36104

You can use $setUnion operator, filters out duplicates in its result to output an array that contain only unique entries,

db.collection.aggregate([
  {
    $addFields: {
      Tags: { $setUnion: "$AllTags" }
    }
  }
])

Playground

Upvotes: 1

Related Questions