Как отсортировать по условию с помощью драйвера Монго в C # - PullRequest
0 голосов
/ 01 октября 2018

Я следовал документации по драйверу 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 я считаю, что оно вычисляет выражение, потому что из отладчика я вижу изменение выражения, как показано ниже:

enter image description here

Итак, два основных вопроса:

  1. Как отсортировать по логическому выражению с помощью драйвера .net mongo.
  2. Почему выражение преобразуется, как показано на скриншоте?

Документация драйвера Mongo (2.4)

1 Ответ

0 голосов
/ 02 октября 2018

Как указано в документации драйвера MongoDB C # (из вставленной ссылки):

Драйвер содержит реализацию LINQ, предназначенную для структуры агрегации .

Таким образом, должна быть соответствующая операция в Aggregation Framework для перевода из LINQ.Вы вызываете .AsQueryable(), что означает, что вы можете построить свое выражение, используя синтаксис LINQ, но затем оно завершается неудачно, когда его необходимо преобразовать в Aggregation Framework.К сожалению, вы не можете иметь выражения внутри $ sort , и поэтому ваш код потерпит неудачу.

Чтобы исправить это, вы можете использовать $ addFields stage, чтобы добавить одно дополнительное поле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 как оператор PipelineStageDefinition и nameof, чтобы он оставался строго набранным:

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...