1

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;
}
8
  • Wouldn't var query = collection.AsQueryable().Where(filter.Compile()).ToString(); be the solution? Commented Sep 18, 2017 at 12:49
  • Hi Skami, In this case when I call ToString() on my collection, in the way you have above, I get System.Linq.Enumerable+WhereEnumerableIterator'1[<MyType>] I am looking for the query that will be sent to Mongo. Commented Sep 22, 2017 at 12:57
  • @Skami that only works with Entity Framework LINQ providers. Commented Sep 22, 2017 at 13:08
  • @Adam P, that's odd. Whenever I run var query = this.collection.AsQueryable().Where(x => x.id == 1).ToString(); I get this as a result aggregate([{ "$match" : { "_id" : 1 } }]). Commented Sep 22, 2017 at 13:08
  • @Amy, according to the source code itself that's not true. Commented Sep 22, 2017 at 15:28

1 Answer 1

1

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();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.