Collapse equivalent in Atlas Search

I have a document for articles.

{
  id: "xxxx"x
  duplicateGroupId: "xxxx",
  ......other fields....
}

After the seach query, I want to get count for both total ids and also unique ‘duplicateGroupId’. And also want the search result to return documents with distinct duplicateGroupId.

First, ensure that you have a search index created… and that you’re referring to it correctly in your search query. Next, you can use grouping by duplicateGroupId to get a count… something like this should work:

const pipeline = [
  // Step 1: Perform the search query
  {
    $search: {
      index: "yourSearchIndex", // Specify your search index name
      text: {
        query: "your search term", // Your search term
        path: "your searchable fields" // Fields to search in
      }
    }
  },
  // Step 2: Group by duplicateGroupId to get distinct documents
  {
    $group: {
      _id: "$duplicateGroupId",
      doc: { $first: "$$ROOT" }
    }
  },
  // Step 3: Unwind the grouped documents to process them in a flat structure
  {
    $replaceRoot: { newRoot: "$doc" }
  },
  // Step 4: Facet to count total documents and unique duplicateGroupId, and return the distinct documents
  {
    $facet: {
      totalDocs: [{ $count: "count" }],
      uniqueDuplicateGroups: [
        { $group: { _id: "$duplicateGroupId" } },
        { $count: "count" }
      ],
      results: [
        { $project: { _id: 1, duplicateGroupId: 1, other_fields: 1 } } // Specify the fields you want in the results
      ]
    }
  },
  // Step 5: Project the results to include counts and the distinct documents
  {
    $project: {
      totalDocs: { $arrayElemAt: ["$totalDocs.count", 0] },
      uniqueDuplicateGroups: { $arrayElemAt: ["$uniqueDuplicateGroups.count", 0] },
      results: 1
    }
  }
];

db.articles.aggregate(pipeline).toArray((err, result) => {
  if (err) throw err;
  console.log(result);
});

The output should look like this:

db.articles.aggregate(pipeline).toArray((err, result) => {
  if (err) throw err;
  console.log(result);
});

[
  {
    results: [ [Object], [Object], [Object], [Object], [Object] ],
    totalDocs: 5,
    uniqueDuplicateGroups: 5
  }
]

Hope this helps… let us know how you make out.

1 Like

You can also use Atlas Search count and facets to get 1) the count of total ids and 2) the count of unique duplicateGroupId, respectively.

Atlas Search facet will return an array of distinct duplicateGroupId, which you could then calculate the length of. Make sure you define duplicateGroupId as a stringFacet field mapping to be able to perform faceting.

1 Like