Можем ли мы использовать несколько вложенных уровней внутри проекции с драйвером MongoDB c #?

#c# #mongodb #mongodb-.net-driver

#c# #mongodb #mongodb-.net-driver

Вопрос:

Представьте, что у нас есть следующие классы в c # 7, dotnet core 3.1, соответствующие данным, хранящимся внутри коллекции MongoDB:

 public class Level1
{
    public string Field1 {get; set;}
    public IEnumerable<Level2> Next1 {get; set;}
}

public class Level2
{
    public string Field2 {get; set;}
    public IEnumerable<Level3> Next2 {get; set;}
}

public class Level3
{
    public string Field3 {get; set;}
    public string Field4 {get; set;}
}
 

По соображениям оптимизации мы хотим получить Field3, но не Field4, и все данные Level1 и Level2. (конечно, это упрощение: есть много данных, которые мы на самом деле хотим игнорировать в реальном случае).

Для этого обычным способом в Mongo является использование проекции. Он отлично работает с запросами JSON, такими как find({}, {"Field1": 1, "Next1.Field2": 1, "Next1.Next2.Field3": 1}) . Мы получаем полную иерархию объектов, но с отсутствующим Field4, т. Е. Именно то, что мы хотим.

Однако я застрял, пытаясь сделать это на c #, используя последнюю версию официального драйвера. Очевидно, я мог бы просто использовать необработанный запрос JSON, и это сработало бы, но я бы пропустил все преимущества управляемого драйвером сопоставления, такие как имена полей после рефакторинга. Итак, мы хотим использовать выражения.

Я пробовал это :

 var result = db.GetCollection<Level1>("mycollection")
    .Find("{}")
    .Project(Builders<Level1>.Projection.Expression(p => new Level1
    {
        Field1 = p.Field1,
        Next1 = p.Next1.Select(s => new Level2
        {
            Field2 = s.Field2,
            Next2 = s.Next2.Select(r => new Level3
            {
                Field3 = r.Field3,
            },
        },
    }));    

 

Однако это приводит к следующему неожиданному JSON:

 find({}
}, {
    "Field1": 1,
    "Next2.Field3": 1,
    "Next1.Next2": 1,
    "Next1.Field2": 1
})
 

и, конечно, это означает, что Field4 не фильтруется — проекция просто неправильная. Похоже, он работает только на двух уровнях и перестает добавлять префиксы к предложениям проекции после двух уровней.

Не могли бы вы знать, есть ли возможность делать то, что я хочу, с выражением? Спасибо!

Ответ №1:

Мы открыли дело в MongoDB, и они подтвердили, что это ошибка на их стороне, на которую ссылаются в их JIRA

Не существует известного обходного пути с использованием выражения объекта, поэтому мы пока используем Include() и обновим его, когда драйвер будет исправлен.