Search code examples
c#mongodbmongodb-querymongodb-.net-driver

MongoDB C# driver - Filter list of array based on specific item id


I am new to using MongoDB C# driver. I have the following in my MongoDB collection. I need to filter the record based on _id something like:

Select * from item where _id = 2 and itemLists.Sizeid = 2

in SQL.

I tried like:

var filter = Builders<Item>.Filter.Eq(x => x.temid, ItemId);
var filter2 = Builders<Item>.Filter.ElemMatch(x => x.itemLists, Builders<ItemList>.Filter.Eq(x => x.Sizeid,sizeId));

var data = await Context.GetCollection<Item>("Item").Find(filter&filter2).FirstOrDefaultAsync();

The above code is not giving me the expected result. Kindly help.

My MongoDB collection data is as below:-

{
    "_id" : NumberInt(2),
    "ItemName" : "Shirt",
    "ItemDescripton" : "Men Trouser",
    "itemLists" : [
        {
            "CategoryId" : NumberInt(1),
            "CategpryName" : "Men",
            "ColorId" : NumberInt(1),
            "ColorName" : "Red",
            "InitialQty" : NumberInt(30),
            "AvailableQty" : NumberInt(28),
            "ReserveQty" : NumberInt(2),
            "Price" : 4560.0,
            "OfferPrice" : 670.0,
            "Images" : [
                "/assets/Images/Men/m4.jpg",
                "/assets/Images/Men/m5.jpg"
            ],
            "Sizeid" : NumberInt(2),
            "SizeName" : "XL",
            "DetailId" : NumberInt(0),
            "DeliveryCharges" : NumberInt(20),
            "Brand" : "Allen Solly",
            "CreatedOn" : ISODate("2022-12-07T17:10:19.881+0000"),
            "CreatedBy" : "string",
            "Active" : true
        },
        {
            "CategoryId" : NumberInt(1),
            "CategpryName" : "Men",
            "ColorId" : NumberInt(2),
            "ColorName" : "Blue",
            "InitialQty" : NumberInt(10),
            "AvailableQty" : NumberInt(6),
            "ReserveQty" : NumberInt(4),
            "Price" : 1400.0,
            "OfferPrice" : 1200.0,
            "Images" : [
                "/assets/Images/Men/m3.jpg",
                "/assets/Images/Men/m4.jpg"
            ],
            "Sizeid" : NumberInt(1),
            "SizeName" : "XL",
            "DetailId" : NumberInt(0),
            "DeliveryCharges" : NumberInt(120),
            "Brand" : "Allen Solly",
            "CreatedOn" : ISODate("2022-12-07T17:10:19.881+0000"),
            "CreatedBy" : "string",
            "Active" : true
        }
    ]
}

Solution

  • From your question and comments, you are expecting the queried document to be filtered with the itemLists array for the sizeId criteria.

    You need a ProjectionDefinition with ElemMatch in order to achieve it.

    ProjectionDefinition<Item> projection = Builders<Item>.Projection
        .Include(x => x.Itemid)
        .Include(x => x.ItemName)
        .Include(x => x.ItemDescripton)
        .ElemMatch(x => x.itemLists, Builders<ItemList>.Filter.Eq(y => y.Sizeid, sizeId));
    
    var data = await _collection.Find(filter & filter2)
        .Project<Item>(projection)
        .FirstOrDefaultAsync();
    

    Demo