Mike Hofer
Mike Hofer

Reputation: 17022

How to retrieve a property from an object within a dictionary in a MongoDB document?

Our Mongo data looks like this:

{
        "_id" : ObjectId("542d881b8bc641bbee1f8509"),
        "ExtendedProperties" : {
                "Context" : {
                        "_t" : "LoggingContext",
                        "DeclaringTypeName" : "EndpointConfig"
                }
        }
}

In the C# code, the ExtendedProperties are represented as follows:

public class LogEntry
{
    public IDictionary<string, object> ExtendedProperties { get; set; }
}

I have tried every method I can find to be able to query against the value of DeclaringTypeName. Nothing seems to work, as shown in the following code:

// This throws an UnsupportedOperationException with the following message:
// Unable to determine the serialization information for the expression: (LogEntry e) => e.ExtendedProperties.get_Item("DeclaringTypeName").ToString().
query.Add(Query<LogEntry>.EQ(e => ((LoggingContext)e.ExtendedProperties["Context"]), this.DeclaringTypeName ));

// This returns zero matching rows:
query.Add(Query.EQ("ExtendedProperties.Context.DeclaringTypeName", this.DeclaringTypeName));

// This returns zero matching rows:
query.Add(Query.ElemMatch("ExtendedProperties.Context", Query.EQ("DeclaringTypeName", this.DeclaringTypeName)));

// This reports that ExtendedProperties must implement a specific interface and must not return null:
query.Add(Query<LogEntry>.ElemMatch(e => e.ExtendedProperties, qb => Query.EQ("Context.DeclaringTypeName", this.DeclaringTypeName)));

For clarity, I have researched every StackOverflow, CodePlex, and Mongo.org thread I can find, and have as yet been unable to resolve this correctly.

Naturally, it's going to be something I'm doing wrong.

Someone please throw me a bone.

Upvotes: 3

Views: 1431

Answers (1)

Disposer
Disposer

Reputation: 6371

I defined the LogEntry class as

public class LogEntry
{
    public ObjectId Id { get; set; }
    public IDictionary<string, object> ExtendedProperties { get; set; }
}

then I inserted the sample document by

var log = new LogEntry
{
    ExtendedProperties = new Dictionary<string, object>
    {
        {
            "Context", new LoggingContext
            {
                DeclaringTypeName = "EndpointConfig"
            }
        }
    }
};

collection.Insert(log);

then I performed the query by:

var rawQuery = Query.EQ("ExtendedProperties.Context.DeclaringTypeName", "EndpointConfig");
var query = new List<IMongoQuery>();
query.Add(rawQuery);

var rawResult = collection.Find(rawQuery).ToList();

the query will send mongo below query

db.messages.find({ "ExtendedProperties.Context.DeclaringTypeName" : "EndpointConfig" })

And I got the result

Upvotes: 1

Related Questions