如何在C#中使用mongo驱动程序按条件排序

时间:2018-10-01 17:31:13

标签: c# mongodb mongodb-query aggregation-framework mongodb-.net-driver

我一直在关注mongo驱动程序(2.4)文档,并且目前在尝试将条件作为排序时陷入困境。

在文档之后,我得到了一个AsQueryable实例,并使用了带传入表达式的where函数。在我要按条件而不是按字段排序之前,这种方法一直有效。

这是我要订购的商品:

net::ERR_INTERNET_DISCONNECTED

应该与linq中的类似

db.child.AsQueryable().Where(expression).OrderBy(x=> x.parentId == someParentId); 

但是,当前,在运行OrderBy条件后,我相信它正在评估表达式,因为从调试器中我可以看到表达式变化,如下所示:

enter image description here

因此,两个主要问题是:

  1. 如何使用.net mongo驱动程序按布尔表达式进行排序。
  2. 为什么如屏幕截图所示转换表达式?

Mongo Driver Documentation (2.4)

1 个答案:

答案 0 :(得分:2)

如MongoDB C#驱动程序文档所述(来自粘贴的链接):

  

驱动程序包含针对聚合框架的LINQ实现。

因此,在Aggregation Framework中必须有相应的操作才能从LINQ进行翻译。您调用.AsQueryable(),这意味着您可以使用LINQ语法构建表达式,但是当需要转换为Aggregation Framework时,它将失败。不幸的是,$sort中不能包含表达式,这就是为什么您的代码将失败的原因。

为解决此问题,您可以使用$addFields阶段添加一个附加字段MatchesParent并按该字段排序。

假设您的模型由以下类表示:

public class Model
{
    [BsonId]
    public ObjectId Id { get; set; }
    public string ParentId { get; set; }
    // some other properties
}

您可以添加以下课程:

public class ModelResult: Model
{
    public bool MatchesParent { get; set; }
}

然后可以将$addFields定义为PipelineStageDefinitionnameof运算符以使其保持强类型:

PipelineStageDefinition<Model, ModelResult> addFields = new BsonDocument() {
            { "$addFields", new BsonDocument() {
                    { nameof(ModelResult.MatchesParent), new BsonDocument() {
                        { "$eq", new BsonArray() { "$" + nameof(Model.ParentId), someParentId } }
                    }
                }
            }
        }
    };

var result = Col.Aggregate()
                .Match(expression)                           
                .AppendStage(addFields)
                .SortByDescending(x => x.MatchesParent)
                .ToList();