24

I have many complex queries that I sometimes wish to check directly against Mongo for debugging \ explaining() purposes. With the newer 2.0+ c# driver, i'm not sure how to do this. With the previous version there was a thing called IMongoQuery and This worked.

A simple example:

FilterDefinition<LalalaEvent> filter = Builders<LalalaEvent>.Filter
    .Where(e => ids.Contains(e.Id) && e.Deleted != true );
Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Shy Peleg
  • 605
  • 1
  • 6
  • 9

3 Answers3

50

I was trying to solve the same problem today. Here is what I found.

public static class MongoExtensions
{
    public static BsonDocument RenderToBsonDocument<T>(this FilterDefinition<T> filter)
    {
        var serializerRegistry = BsonSerializer.SerializerRegistry;
        var documentSerializer = serializerRegistry.GetSerializer<T>();
        return filter.Render(documentSerializer, serializerRegistry);
    }
}

I didn't have access to a collection when I was calling it, so I couldn't use the above solutions.

This allows you to do

var json = filter.RenderToBsonDocument().ToJson();
zrbecker
  • 1,394
  • 1
  • 19
  • 39
  • 1
    Does anyone know how this could be done with IAggregateFluent? – eatinasandwich Feb 26 '18 at 17:28
  • @Aneef, I think the other answer had already been accepted when I posted my solution. I appreciate the perpetual stream of upvotes I seem to have gotten for my solution though. haha. – zrbecker Apr 19 '18 at 18:55
  • RenderToBsonDocument throws exception when a field is repeted in the filter, ex: {"myField": { $exists: true }, "myField" : {$ne:""}} – FDB Oct 10 '19 at 08:23
27

If you're using the latest version of the driver, which is 2.0.1 you can easily put that filter in a Find operation, get back an IFindFluent and print its ToString:

var filter = Builders<LalalaEvent>.Filter.Where(e => ids.Contains(e.Id) && e.Deleted != true);
var findFluent = collection.Find(filter);
Console.WriteLine(findFluent);

For example for me this prints:

find({ "_id" : { "$in" : [1, 2, 3] }, "Deleted" : { "$ne" : true } })
i3arnon
  • 113,022
  • 33
  • 324
  • 344
22

You are able to perform that using the collection's properties:

var result = filter.Render(collection.DocumentSerializer,
                           collection.Settings.SerializerRegistry).ToString();
Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Vladyslav Furdak
  • 1,765
  • 2
  • 22
  • 46
  • 7
    This seems very weird. Why should I need a collection to convert a FilterDefinition to a json string? I see it works, it just doesn't feel like the way one ought to go about it. – zrbecker Aug 21 '15 at 17:03
  • @zrbecker After five years, this is exactly what I was looking for. I already have the collection and wanted see what's going on with the filter. This is a short and neat solution for some cases. – superkeci Dec 19 '20 at 19:32