[CSHARP-1194] Support for adding Discriminators to a collection Automatically Created: 17/Mar/15  Updated: 20/Jan/16  Resolved: 03/Sep/15

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: 2.1

Type: New Feature Priority: Major - P3
Reporter: Craig Wilson Assignee: Craig Wilson
Resolution: Done Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently, when using a hierarchy of types (Animal -> Cat, Dog), it is required to always use the base class as the generic type on collection (Animal).

That's fine, but if I only want to then work with Cats, I must add the discriminator in manually to every filter. There should be a way to do this automatically.

------------------------
There is currently a commit here (https://github.com/craiggwilson/mongo-csharp-driver/tree/oftype) that adds a method called OfType to IMongoCollection<T> which does this exact thing. It includes the discriminator with every filter.

For instance, `db.GetCollection<Animal>("animals").OfType<Cat>();` returns an IFilteredMongoCollection<Cat>, which implements IMongoCollection<Cat>. From here, everything that can be done on a normal collection can be done on this collection, except the discriminator will be added to all filters.



 Comments   
Comment by Githook User [ 03/Sep/15 ]

Author:

{u'username': u'rstam', u'name': u'rstam', u'email': u'robert@robertstam.org'}

Message: CSHARP-1194: Refactor MongoCollectionImpl OfType method to use new OfType FilterDefinitionBuilder method.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/76209b0c932cfb9cd9777cbdb436d844b62135c9

Comment by Githook User [ 03/Sep/15 ]

Author:

{u'username': u'rstam', u'name': u'rstam', u'email': u'robert@robertstam.org'}

Message: CSHARP-1194: Craig's further code review changes.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/1e576efd9f648b0d07e762aefdb69390ca2dbde0

Comment by Githook User [ 03/Sep/15 ]

Author:

{u'username': u'rstam', u'name': u'rstam', u'email': u'robert@robertstam.org'}

Message: CSHARP-1194: Code review changes.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/f0b381e63c4236560ac9240d810bd264fc1dffe6

Comment by Githook User [ 03/Sep/15 ]

Author:

{u'username': u'craiggwilson', u'name': u'Craig Wilson', u'email': u'craiggwilson@gmail.com'}

Message: CSHARP-1194: added polymorphic support into IMongoCollection<T> using the OfType method.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/32475614f3caadab37410c8f1502497d78d1a803

Comment by Robert Stam [ 16/May/15 ]

The problem with the approach of creating a filtered collection is that it doesn't represent at all the reality of what's in the database.

Given a variable:

    IMongoCollection<Cat> collection;

I would expect that it represents a collection that contains Cats. But the database has no such collection. What the database has is a collection of Animals, some of which might be Cats.

Furthermore, all operations against such a collection are misleading. For example, given:

    var count = await collection.CountAsync("{}");

I would expect count to be the number of documents stored in the collection. But in the proposed filtered collection implementation that wouldn't be true, it would actually only return the count of the Cats in the collection (by design of course, but it's misleading).

Further examples of confusion can arise in queries. For example, the following Find might not return any documents:

    var list = await collection.Find("{ Name : 'Spots' }").ToListAsync();

Even if the collection has plenty of documents with the name "Spots". It all depends on whether there are any Cats named "Spots", but that important detail is hidden away in a side effect.

I think our emphasis should be on making it easier to issue queries against polymorphic collections, not on creating filtered collections that don't correspond to anything that actually exists in reality.

It would be far more transparent to simply embrace the notion that certain types of queries imply that the matching documents are of a certain type, and take advantage of that.

For example, one could write (where OfType would be a new filter builder method):

    var builder = Builders<Animal>.Filter;
    var list = await collection.Find(builder.OfType<Cat>() & "{ Name : 'Spots' }").ToListAsync();

In this case, not only is nothing hidden (we immediately see that we are only querying Cats, this is not hidden in some side effect!), but we can take advantage of the type information in the OfType filter to automatically make the result be of type List<Cat> instead of List<Animal>.

Generated at Wed Feb 07 21:38:56 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.