2

I'm trying to do a multiple field "distinct" query, which of course isn't possible
(see my attempt here: Selecting a new type from linq query)

Following my realization of this, I've found I'm able to retrieve the data I need by using .group with MongoDB.

Is there any way of using the following query / command within the MongoDB C# wrapper?

disciplines = db.result.group({ 
    key: {DisciplineName:1, DisciplineCode:1}, 
    reduce: function(obj, prev) { if (!obj.hasOwnProperty("DisciplineName")) { 
        prev.DisciplineName = obj.DisciplineName; 
        prev.DisciplineCode = obj.DisciplineCode; 
    }}, 
    initial: { } 
});

My Result class (document) looks like:

public class Result
{
    public virtual int ResultId { get; set; }
    public virtual string DisciplineCode { get; set; }
    public virtual string DisciplineName { get; set; }
    public virtual int CompetitorId { get; set; }
    //other stuff
}
Community
  • 1
  • 1
Alex
  • 37,502
  • 51
  • 204
  • 332

1 Answers1

3

Resolved using:

var initial = new BsonDocument();

//return a list of keys for the group
var keyFunction = (BsonJavaScript)@"function(doc) { 
                                        return { 
                                            DisciplineName : doc.DisciplineName, 
                                            DisciplineCode: doc.DisciplineCode 
                                        }; 
                                    }";

var reduce = @"function(obj, prev) {
                    if (!obj.hasOwnProperty(""DisciplineName"")) {
                        prev.DisciplineName = obj.DisciplineName; 
                        prev.DisciplineCode = obj.DisciplineCode;
                    }
                }";

var bsonDocs = _db.GetCollection("result").Group(Query.Exists("DisciplineName"), keyFunction, initial, reduce, null).ToArray();

//I hate this!!
var disciplines = new List<Discipline>();

foreach (var item in bsonDocs)
    disciplines.Add(BsonSerializer.Deserialize<Discipline>(item));

I'm really unfond of the way I have to iterate over the IEnumerable<BsonDocument> to serialize each one into a Discipline object.

Will update if it's possible to deserialize a collection of BsonDocuments

Alex
  • 37,502
  • 51
  • 204
  • 332
  • Keep in mind that Map/Reduce is NOT build for real-time querying. It is very slow and has some other repercussions while it is in use. The better way would be to have a separate collection that contains these results pre-calculated. – Craig Wilson Jul 09 '12 at 12:23
  • I realize that.. but in my domain this separate collection is going to be quite a pain. I intend to cache the result of the above map/reduce for several hours / indefinitely (until Result collection is updated every night) – Alex Jul 09 '12 at 13:02