Search code examples
c#mongodb-.net-driver

C# driver and shell produces different result


I have two collections; ProductStemCollections, ProductStems.

    public abstract class Document : IDocument
    {
        [BsonId]
        [BsonRepresentation( BsonType.String )]
        public ObjectId Id { get; set; }
    }

    [BsonCollection( "ProductStemCollections" )]
    public class ProductStemCollection : Document
    {
        public string Name { get; set; }

        [BsonRepresentation( BsonType.String )]
        public List<ObjectId> ProductStems { get; set; } = new List<ObjectId>();
    }

    [BsonCollection( "ProductStems" )]
    public class ProductStem : Document
    {
        [BsonRepresentation(BsonType.String)]
        public ObjectId PromotedProductId { get; set; }

        public string ProductCode { get; set; }
    }

I want to aggregate stems listed in a stem collection, like so:

            var query = prodStemCollectionRepo.Collection
                .Aggregate()
                .Lookup( "ProductStems", "ProductStems", "_id", "stems" );

            var strQuery = query.ToString();
            var results = await query.ToListAsync();

This will produce query

db.ProductStemCollections.aggregate([{ "$lookup" : { "from" : "ProductStems", "localField" : "ProductStems", "foreignField" : "_id", "as" : "stems" } }])

If I run this query in the Cosmos db shell, I get the desired result:

{
    "_id" : "61694434ba77dc8362d56858",
    "Name" : "Sweden",
    "ProductStems" : [
        "61694434ba77dc8362d56859",
        "61694434ba77dc8362d5685b",
        "61694435ba77dc8362d5685d",
        "61694435ba77dc8362d5685f",
        "61694436ba77dc8362d56861",
        "61694438ba77dc8362d56863"
    ],
    "stems" : [
        {
            "_id" : "61694434ba77dc8362d56859",
            "PromotedProductId" : "61694434ba77dc8362d5685a",
            "ProductCode" : "P1"
        }
        ...
    ]
}

However, running the C# code above does not produce the same result, even though the query is the same array "stems" is missing:

{
    {
        "_id": "61694434ba77dc8362d56858",
        "Name": "Sweden",
        "ProductStems": [
            "61694434ba77dc8362d56859",
            "61694434ba77dc8362d5685b",
            "61694435ba77dc8362d5685d",
            "61694435ba77dc8362d5685f",
            "61694436ba77dc8362d56861",
            "61694438ba77dc8362d56863"
        ]
    }
}

What am I missing?


Solution

  • Ok, so I ended up moving to Mongo Db Atlas. Created a aggregate class that holds a stem collection with its stems:

            public class AggregatedStemCollection : Document
            {
                public string? Name { get; set; }
                
                [BsonRepresentation(BsonType.String)]
                public List<ObjectId> ProductStems { get; set; } = new List<ObjectId>();
    
                public List<ProductStem> Stems { get; set; } = new List<ProductStem>();
            }
    

    And modified the lind query:

                var query = prodStemCollectionRepo.Collection
                    .Aggregate()
                    .Match( c => c.Name == "Sweden" )
                    .Lookup(
                        foreignCollection: productStemRepo.Collection,
                        localField: x => x.ProductStems,
                        foreignField: y => y.Id,
                        @as: ( AggregatedStemCollection asc ) => asc.Stems );
    
                var results = query.ToList();