繁体   English   中英

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

[英]How to sort by condition using the mongo driver in c#

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

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

以下是我要订购的商品:

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

这应该是在linq的路线

SELECT * FROM child
ORDER BY
  CASE parentId
  WHEN someParentId THEN 1
  ELSE 2 END,
  parentId; 

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

在此处输入图片说明

因此,两个主要问题是:

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

Mongo驱动程序文档(2.4)

如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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM