Adam P
Adam P

Reputation: 129

Visualizing MongoDB C# Linq query for Driver version 2.4

I’m working with the 2.4 version of the C# Mongo Driver. I have found a lot of traffic on how to visualize (or explain) a query for previous versions or legacy C# Mongo Driver support. I’m not having any luck understanding how to see the native Mongo query behind my version 2.4 Linq. In my specific case I am using PredicateBuilder to build a complex expression, which I then pass into the collection like this:

var s = collection.AsQueryable().Where(filter.Compile());

After that I can further refine the query as needed by adding skip, take, etc. Finally I can call .ToArray() and the query executes.

I have tried to enable “--profile 2 --slowms 15” on my Mongod instance, and I have verified that the profile level is 2 with db.getProfilingLevel(). I can clearly see logged queries when running adhoc queries via RoboMongo, or even when using the collection.find method from the c# Mongo 2.4 driver.

However, when I call .ToArray on my Linq query I cannot find the query sent to Mongo either though a logging method I know, or though some aspect of the c# driver itself.

If I instead rework my code to use BsonDocuments and the builder object, I can see the query – but I’d rather use Linq.

Can anyone help me to see the underlying query being sent to Mongo while using Linq and the Mongo 2.4 C# driver?

Relevant URL: http://mongodb.github.io/mongo-csharp-driver/2.4/reference/driver/crud/linq/ http://mongodb.github.io/mongo-csharp-driver/2.4/reference/driver/crud/reading/#aggregation

Notice for the 'reading section' there is a Note that explains you can call ToString on the pipeline to see what will be sent to the server. I can access the pipeline when using the BsonDocuments/Builder method of creating a query, but not when I use the Linq method.

Update: This seems to be related to filter.compile. If I don't use that, I can use .ToString() to view the query!

var sfilter = PredicateBuilder.True<MediaItem>();
var sTest = collection.AsQueryable().Where(sfilter.Compile()).Where(f => f.MediaItemType == MediaItemTypes.Image);
var sString = sTest.ToString();
// System.Linq.Enumerable+WhereEnumerableIterator'1[Common.Domain.MediaItem]

var xTest = collection.AsQueryable().Where(f => f.MediaItemType == MediaItemTypes.Image);
var xString = xTest.ToString();
// aggregate([{ "$match" : { "MediaItemType" : 1 } }])

The definition of PredicateBuilder.True:

public static Expression<Func<T, bool>> True<T>()
{
    return f => true;
}

Upvotes: 1

Views: 1236

Answers (1)

Skami
Skami

Reputation: 1576

Okay so after reading your update I believe I may have found the solution to your problem. Mongo has no overload for the compiled version of your predicate which returns a Func<MediaItem, bool>, however there is as expected an overload for [Expression<Func<MediaItem, bool>>.

So the following code should work for you.

var sfilter = PredicateBuilder.True<MediaItem>();
var sTest = collection.AsQueryable().Where(sfilter).Where(f => f.MediaItemType == MediaItemTypes.Image);
var sString = sTest.ToString();

Upvotes: 1

Related Questions