Context:

I maintain two collections: Package and Module. Within the Module collection, each document contains a field called packageId, which corresponds to the _id field of a document in the Package collection.

Sample document from Package collection

  "_id": "660dc62edb464b62c8e34b3b",
  "workspaceId": "6606a50d59b56908f026a3ab",
  "packageUUID": "6605b2ee536675159c565857",
  "originPackageId": "6606a51359b56908f026a3b2",
  "version": "0.0.7",
  "latest": true
}

Sample document from Module Collection

  "_id": "660dc62edb464b62c8e34b3c",
  "packageUUID": "6605b2ee536675159c565857",
  "packageId": "660dc62edb464b62c8e34b3b",
  "version": "0.0.7",
  "type": "QUERY_MODULE",
  "moduleUUID": "6605b324536675159c565869",
  "originModuleId": "6606a51359b56908f026a3bc"
}

My Use Case:

When provided with a list of module IDs (i.e., _ids in the Module collection), I aim to tally the number of packages that meet the following criteria:

Either the originPackageId field does not exist.
Or the latest field is set to true.

My attempt:

Here is what I attempted but it always returns 0

public long countPackages(List<String> moduleIds) {
        AggregationOperation matchModuleIds =
                Aggregation.match(Criteria.where(Module.Fields.id).in(moduleIds));

        LookupOperation lookupOperation = LookupOperation.newLookup()
                .from("package")
                .localField("packageId")
                .foreignField("_id")
                .as("packages");

        AggregationOperation unwindPackages = Aggregation.unwind("$packages"); // tried without `$` as well

        AggregationOperation matchConditions = Aggregation.match(new Criteria()
                .orOperator(
                        Criteria.where("packages.originPackageId").exists(false),
                        Criteria.where("packages.latest").is(true)));

        AggregationOperation groupByNull = Aggregation.group().count().as("total");

        Aggregation aggregation = Aggregation.newAggregation(
                matchModuleIds, lookupOperation, unwindPackages, matchConditions, groupByNull);

        List<Document> results = mongoTemplate
                .aggregate(aggregation, Module.class, Document.class)
                .getMappedResults();

        // Assuming there is only one result
        if (!results.isEmpty()) {
            Document resultDoc = results.get(0);
            return resultDoc.get("total", Long.class);
        } else {
            return 0L;
        }
    }

I appreciate your help in this regard.