Reputation: 129
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
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