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

MongoDB - Mapping map-reduce collections in C#


I am running a map reduce job that dumps the resulting data into a collection, the elements in the "products" collection look like this (the structure is generated by Mongo and I'm not aware if it can be controlled):

{
    "_id" : { "ProductId" : "1:000001", "ProductTitle" : "Some product with ID 1:000001" }, 
    "value" : { "TotalImpressions" : 3, "TotalClicks" : 40 } 
}

Ideally, I want to map each entry to the following flat object:

public class Product 
{
    public string ProductId { get; set; }
    public string ProductTitle { get; set; }
    public int TotalImpressions { get; set; }
}

This obviously doesn't work as the serializer looks for properties "id" and "value" at the root level, which don't exist on that class. The workaround I have in place is to model the object as they appear, e.g.:

public class ProductRow
{
    /* implementation of these objects excluded, but they just reflect the json objects */
    public ProductIdentifier Id { get; set; }
    public Product value { get; set; }
}

Which maps fine, however it's a little verbose and I'd rather avoid having all those extra objects.

Is it possible to configure the BSON deserializer to support this mapping? I've had a look through the documentation, but haven't seen any obvious solution.

NB: I am restricted by working environment to .NET 3.5, so please bear that in mind when considering an answer.


Solution

  • You can easy do deserialization yourself(as @Avish suggested), so here is complete example for your case:

    var mongoServer = MongoServer.Create("mongodb://localhost:27020");
    var database = mongoServer.GetDatabase("StackoverflowExamples");
    var products = database.GetCollection("products");
    
    var result = new Product();
    
    var item = products.FindOne();
    var id = item["_id"].ToBsonDocument();
    var value = item["value"].ToBsonDocument();
    
    result.ProductId = id["ProductId"].AsString;
    result.ProductTitle = id["ProductTitle"].AsString;
    result.TotalImpressions = value["TotalImpressions"].AsInt32;