Question

I have a mongo model like this:

class ObjectA {
        [BsonId(IdGenerator = typeof(BsonObjectIdGenerator))]
        public BsonObjectId Id;

        [BsonElement("number")]
        public int Number { get; set; }

        [BsonElement("b")]
        public List<ObjectB> objectB { get; set; }
}

class ObjectB {
        [BsonElement("someProperty")]
        public string SomeProperty { get; set; }
}

My problem is when I aggregate the collection with {$unwind:objectB}. The result documencts have a unique object on the property objectB (not a list). So the cast failes with the exception:

An error occurred while deserializing the ObjectB property of class ObjectA: Expected element name to be '_t', not 'number'.

Do I have to create a new model for this or is there a easier way to solve it?

Was it helpful?

Solution

You could also choose to work with BsonDocument directly (but that is not strongly typed and more cumbersome to work with), e.g. (I'm using the simple Posts/Tags example here)

var aggregationResults = db.GetCollection("Posts").Aggregate().ResultDocuments;
foreach (var document in aggregationResults)
{
    var tag = document.GetValue("Tags").AsString;
}

Unlike the normal query and projection operators, the aggregation framework may change the structure of your document. As you already pointed out, $unwind transforms a document that contains an array into a number of documents that each have a single value of the same name.

Another approach this is to indeed create a new type for this, so

class Post {
    public List<string> Tags { get; set; }
    ...

would become

class PostAggregationResult {
    public string Tags { get; set; }
    ...

That is very easy to work with, but if you have very various aggregation queries, you need a large number of classes which can be annoying.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top