Search code examples
mongodbaggregation-frameworkmongodb-.net-driver

MongoDB - How to tell if every document has an exactly matching element array after an aggregate match


I have a collection of documents similar to this:

{
    Name : "Name1",
    Product : 1012,
    Titles : [ { 
         Id: 5,  
         Title: "FirstTitle" 
         }, 
         {
         Id: 75,
         Title: "SecondTitle"
         }
 },
 {
    Name : "Name1",
    Product : 2014,
    Titles : [ { 
         Id: 5,  
         Title: "FirstTitle" 
         }, 
         {
         Id: 75,
         Title: "SecondTitle"
         }
 }

I'm matching by the Name with an aggregate to get all documents with the same name. Then if all matches have the exact same set of Titles, I want that set.

{
    Name : "Name1,
    TitlesVaries : false
    Titles : [ { 
         Id: 5,  
         Title: "FirstTitle" 
         }, 
         {
         Id: 75,
         Title: "SecondTitle"
         }
}

If they are different I want to know that.

{
    Name : "Name1"
    TitlesVaries : true
    Titles : null
}

I'm having trouble comparing the set/array titles for each document to see if they are all exactly the same after I've don't my aggregate/match. Some documents can have empty/null arrays of Titles and if they are all empty/null that's a match


Solution

  • The aggreagtion might be

    • $addToSet helps to remove duplicates. So we will have two array which is a Set (Titles) and an original array ('original')
    • Compare both array. If both are not equal, then there is a various.

    The script is

    db.collection.aggregate([
      {
        $group: {
          _id: "$Name",
          Titles: { $addToSet: "$Titles" },
          original: { $push: "$Titles" }
        }
      },
      {
        $project: {
          Titles: {
            $cond: [
              {
                $or: [
                  {
                    $ne: [
                      { $size: "$Titles" },
                      { $size: "$original" }
                    ]
                  },
                  {
                    $eq: [ {  $size: "$original"  }, 1 ]
                  }
                ]
              },
              "$Titles",
              null
            ]
          },
          TitlesVaries: {
            $ne: [
              { $size: "$Titles" }, { $size: "$original" }
            ]
          }
        }
      }
    ])
    

    Working Mongo playground