MongoDb 3.4 C#驱动程序 - 如何使用C#驱动程序创建相当的聚合查询

3

我需要帮助将一个MongoDB查询转换为C#查询。 这是我的模式:

public class Planner  
{
    public ObjectId Id { get; set; }
    public string PlannerName { get; set; }
    public string EditorName { get; set; }
    public DateTime DateModified { get; set; }
    public List<PlannerDayModel> PlannerDays { get; set; }
}

public class PlannerDayModel 
{
    public int WeekDay { get; set; }
    public string WeekDayStr { get; set; }
    public int Month { get; set; }
    public int Year { get; set; }
    public int MonthDay { get; set; }
    public DateTime TimeStamp { get; set; }
    public bool IsWeekend { get; set; }
    public bool IsHoliday { get; set; }
    public PlannerFreeTextModel FreeTextBox1 { get; set; }
    public PlannerFreeTextModel FreeTextBox2 { get; set; }
    public List<PlannerEventModel> Events { get; set; }
}

public class PlannerEventModel
{
    public int EventRowId { get; set; }
    public string EventName { get; set; }
    public bool IsSeries { get; set; }
    public int? Episode { get; set; }
    public int? Season { get; set; }
    public bool? IsCustom{ get; set; } 
}

public class PlannerFreeTextModel
{
    public int EventRowId { get; set; }
    public string Text { get; set; }
}

我正在尝试获取所有计划程序文档,其中一个名为Events的嵌套集合具有事件名称为x的事件。

这个MongoDB查询很好用:

db.Planner.aggregate([
  { "$match": { "planners.events.eventName": "X" } },
  { "$project": 
  {"dateModified":1, "editorName":1,"plannerName":1,
      "planners": {
      "$filter": {
        "input": {
          "$map": {
            "input": "$planners",
            "as": "planner",
            "in": {
              "weekDay": "$$planner.weekDay",
              "weekDayStr":"$$planner.weekDay",
              "events": {
                "$filter": {
                  "input": "$$planner.events",
                  "as": "event",
                  "cond": {
                    "$eq":  ["$$event.eventName", "X" ]
                  }
                }
              }
            }
          }
        },
        "as": "planner",
        "cond": { "$ne": [ "$$planner.events", []]}
      },
    }
  }}
])

但我无法找到等效的C#驱动程序查询来工作。
我尝试了这个,但它抛出了错误“无法确定表达式的序列化信息”。
var projection = Builders<Planner>.Projection
    .Include(x => x.PlannerDays
        .Find(p => p.Events.FirstOrDefault(e => e.EventName == eventName) != null))
    .Include(x => x.DateModified)
    .Include(x => x.EditorName)
    .Include(x => x.Id)
    .Include(x => x.PlannerName);

var res = collection
    .Aggregate()
    .Match(Builders<Planner>.Filter.Eq("planners.events.eventName", eventName))
    .Project<Planner>(projection)
    .ToList();
1个回答

3

我觉得你把它弄复杂了。首先,你可以在c#查询的结尾处添加ToString()来检查查询。例如:

collection.Aggregate()
    .Match(Builders<Planner>.Filter.Eq("planners.events.eventName", eventName))
    .Project<Planner>(projection)
    .ToString();

第二件事,让我们回到你的问题上来,你想要带有条件的所有计划者。 你可以这样做。 首先,你的过滤器应该是这样的:

var filter = Builders<BsonDocument>.Filter.Eq("Planner.PlannerDayModel.PlannerEventModel.eventName", "X");

现在是您的聚合查询:
 var aggregate = collection.Aggregate(new AggregateOptions { AllowDiskUse = true })
                    .Unwind("Planner")
                    .Unwind("Planner.PlannerDayModel")
                    .Unwind("Planner.PlannerDayModel.PlannerEventModel")
                    .Unwind("Planner.PlannerDayModel.PlannerEventModel.eventName")
                    .Match(filter)
                    ;

现在这将是您的C#查询。您可以通过以下方式检查模式:
aggregate.ToString();

现在让我们执行查询。
List<JObject> objList = new List<JObject>();
 foreach (var agg in aggregate.ToList())
                {
                    JObject obj = new JObject();
                    var str = agg.ToString();
                    objList.Add(obj);
                }

你将在 objList 中获得所有规划器的数据。 除此之外,你可以根据自己的需要使用项目。 请随意纠正我。 编辑:添加项目。
var pro = new BsonDocument {
                    {"PlannerName", true },
                    {"EditorName", true },
                    {"DateModified", true },
                    {"PlannerDays", true }
                };

现在聚合查询应该是这样的:
var aggregate = collection.Aggregate(new AggregateOptions { AllowDiskUse = true })
                        .Unwind("Planner")
                        .Unwind("Planner.PlannerDayModel")
                        .Unwind("Planner.PlannerDayModel.PlannerEventModel")
                        .Unwind("Planner.PlannerDayModel.PlannerEventModel.eventName")
                        .Match(filter)
                        .Project(pro)
                        ;

希望能帮到您。 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接