Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB c# Driver - Perform a LINQ "Any" in a Serialized Dictionary

I have a document type with some attributes, one of which is a Dictionary< string, string >.

Serialization and De-serealization seem to work fine (I can search, perform CRUD operations, etc.). The problem is that I'm trying to write a method to find all the objects of that type where the dictionary contains a specific value (id) among its Keys.

Attempted Query:

var objectCollection = db.GetCollection<MyClass>("MyClass");

var query = Query<MyClass>.Where(m => m.MyDictionary.Any(k => k.Key == id));

The Class:

public class MyClass
{

    public ObjectId Id { get; set; }
    // ...
    [BsonElement("Dictionary")]
    public Dictionary<string, string> MyDictionary { get; set; }
}

...but I get this Exception while building the query:

Any requires that the serializer specified for Dictionary support items by implementing 
MongoDB.Bson.Serialization.IBsonArraySerializer and returning a non-null result. 
MongoDB.Bson.Serialization.Serializers.DictionarySerializer`2[System.String,System.String] 
is the current serializer.

I suspect the problem is related to the fact that the c# driver's default serializer doesn't support this. Is there a workaround?

I've also tried to perform a "Contains" for the id string on the Dictionary.Keys collection, but that gives a NotSupportedException: Unable to determine the serialization information for the expression: m.Dictionary.Keys.

like image 450
user1987392 Avatar asked Apr 07 '14 09:04

user1987392


People also ask

Can you use MongoDB with C#?

By developing with C# and MongoDB together one opens up a world of possibilities. Console, window, and web applications are all possible. As are cross-platform mobile applications using the Xamarin framework.

Can I use MongoDB with C++?

You can add the driver to your application to work with MongoDB using the C++11 or later standard. Download the library, mongocxx , from mongocxx.org or set up a runnable project by following our tutorial.

What is a MongoDB driver?

The official MongoDB Node. js driver allows Node. js applications to connect to MongoDB and work with data. The driver features an asynchronous API which allows you to interact with MongoDB using Promises or via traditional callbacks.


1 Answers

Figured it out on my own...

Added an annotation in MyClass to specify how I want the Dictionary to be serialized (read about DictionarySerializationOptions here for more info).

[BsonElement("Dictionary")]
[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfDocuments)] // Added This!
public Dictionary<string, string> Dictionary { get; set; }

This serializes the Dictionary as an array of Documents, each containing a "k" (key) and "v" (value).

Then I changed my query to:

var query = Query.ElemMatch("Dictionary", Query.EQ("k", id));

This searches entries in my collection in which the Dictionary contains id as one of its keys.

Other relevant links:

  • MongoDB and C# Dictionary Serialisation, Part 1 – The Problem

  • How to query a sub document collection using MongoDB and C# driver

like image 185
user1987392 Avatar answered Oct 11 '22 16:10

user1987392