2

I have this query which works when I run it in Robo 3T:

db.getCollection('groupSchedule').aggregate([{ "$match" : { "GroupId" : ObjectId("598dd346e5549706a80680bf") } }, 
{ "$lookup" : { "from" : "schedule", "localField" : "ScheduleIds", "foreignField" : "_id", "as" : "Schedule" } }, 
{ "$unwind" : "$Schedule" }, 
{ "$match" : {"$or": [{ "Schedule.End.ByDate" : {"$gte":new Date()}},{ "Schedule.End.ByDate" : null}] } }, 
{ "$group" : { "_id" : "$GroupId", "SurveyIds" : { "$addToSet" : "$Schedule.SurveyId" }, "ScheduleIds" : { "$addToSet" : "$Schedule._id" } } }, 
{ "$project" : { "_id" : 0, "SurveyIds" : 1, "ScheduleIds": 1 } }])

However, when I try to do the same thing using the C# driver as it blows up saying that:

"Duplicate element name 'Schedule.End.ByDate'.",

Here's the code:

return new List<BsonDocument>
{
    Common.Util.MongoUtils.Match(new BsonDocument { { "GroupId", groupId } }),
    Common.Util.MongoUtils.Lookup(scheduleCollections, "ScheduleIds", "_id", "Schedule"),
    Common.Util.MongoUtils.Unwind("$Schedule"),
    Common.Util.MongoUtils.Match(new BsonDocument
    {
        {
            "$or", new BsonDocument
            {
                {
                    "Schedule.End.ByDate", BsonNull.Value
                },
                {
                    "Schedule.End.ByDate", new BsonDocument
                    {
                        {
                            "$gte", DateTime.UtcNow
                        }
                    }
                }
            }
        }
    }),
    Group(),
    Common.Util.MongoUtils.Project(new BsonDocument
    {
        { "_id", 0 },
        { "SurveyIds", 1 },
        { "Schedules", 1 }
    })
};

Any thoughts?

1 Answer 1

4

By using BsonDocument for your $or operator, you're effectively trying to create the following:

"$or": {
    "Schedule.End.ByDate": null,
    "Schedule.End.ByDate": { "$gte" : ISODate("...") }
}

If we look again at your error message:

"Duplicate element name 'Schedule.End.ByDate'.",

It's clear that you have duplicated the Schedule.End.ByDate element name, which is invalid and not what was intended.

Instead, you want to use BsonArray to wrap two separate objects, in order to produce the result you have in your Robo 3T query. To achieve that, you can use the following adaptation of your C# code:

"$or", new BsonArray
{
    new BsonDocument
    {
        { "Schedule.End.ByDate", BsonNull.Value }
    },
    new BsonDocument
    {
        {
            "Schedule.End.ByDate", new BsonDocument
            {
                { "$gte", DateTime.UtcNow }
            }
        }
    }
}

This produces the following, which matches your Robo 3T query for the $or section:

{ "$or" : [
    { "Schedule.End.ByDate" : null },
    { "Schedule.End.ByDate" : { "$gte" : ISODate("...") } }
] }
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.