#c# #asp.net-core #mongodb-query
#c# #asp.net-core #mongodb-запрос
Вопрос:
Я пытаюсь выполнить простое развертывание и заменить root в .net core 2.2. Я уже пробовал запрос в MongoDB, и он работает, но мне сложно перевести его на 100% на C # без использования волшебных строк.
Это мой документ:
{
"_id" : ObjectId("5cb6475b20b49a5cec99eb89"),
"name" : "Route A"
"isActive" : true,
"buses" : [
{
"capacity" : "15",
"time" : "08:00:00",
"direction" : "Inbound"
},
{
"capacity" : "15",
"time" : "08:30:00",
"direction" : "Inbound"
},
{
"capacity" : "15",
"time" : "08:00:00",
"direction" : "Outbound"
},
{
"capacity" : "15",
"time" : "08:30:00",
"direction" : "Outbound"
}
]
}
У меня также есть класс для корневого документа под названием Routes и еще один для вложенного документа под названием Bus.
Запрос, который я запускаю в mongo, является следующим:
db.routes.aggregate([
{ $match : { "_id" : ObjectId("5cb4e818cb95b3572c8f0f2c") } },
{ $unwind: "$buses" },
{ $replaceRoot: { "newRoot": "$buses" } }
])
Ожидаемый результат — простой массив шин, пока я получаю его с помощью этого запроса на C#
_routes.Aggregate()
.Match(r => r.Id == routeId)
.Unwind<Route, UnwoundRoute>(r => r.Buses)
.ReplaceRoot<Bus>("$buses")
.ToListAsync();
Я хочу знать, возможно ли заменить строку «$ buses» чем-то, что не задано жестко.
Я пытался использовать класс AggregateExpressionDefinition, который является одним из возможных параметров, которые может получить метод ReplaceRoot, но я не смог его полностью понять.
Любая помощь будет оценена.
Ответ №1:
Публикую это здесь на случай, если кто-то в конечном итоге совершит те же ошибки, что и я.
Я в основном создал новый объект «UnwoundRoute» для хранения результатов операции размотки, а затем использовал простое выражение LINQ. Спасибо пользователю reddit u / Nugsly за предложение об изменении способа, которым я должен вызывать unwind.
Это работает:
_routes.Aggregate()
.Match(r => r.Id == routeId)
.Unwind<Route, UnwoundRoute>(r => r.Buses)
.ReplaceRoot(ur => ur.Buses)
.ToListAsync();
Вы также можете отфильтровать результат замены root впоследствии:
_routes.Aggregate()
.Match(r => r.Id == routeId)
.Unwind<Route, UnwoundRoute>(r => r.Buses)
.ReplaceRoot(ur => ur.Buses)
.Match(b => b.Direction == direction)
.ToListAsync();
И он вернет массив документов.
{
"capacity" : "15",
"time" : "08:00:00",
"direction" : "Inbound"
},
{
"capacity" : "15",
"time" : "08:30:00",
"direction" : "Inbound"
}
Кроме того, если вы попытаетесь добавить тип результата для замены root, VS выдаст сообщение об ошибке, в котором говорится, что лямбда-выражение не удалось преобразовать, поскольку оно не является типом делегата.
Это не так (что у меня было в начале):
_routes.Aggregate()
.Match(r => r.Id == routeId)
.Unwind<Route, UnwoundRoute>(r => r.Buses)
.ReplaceRoot<Bus>(ur => ur.Buses)
.ToListAsync();
Ответ №2:
я могу предложить вам решение, которое использует MongoDAL, который является просто оболочкой вокруг драйвера c #, который скрывает большую часть сложности драйвера.
using System;
using System.Linq;
using MongoDAL;
namespace BusRoutes
{
class Route : Entity
{
public string name { get; set; }
public bool isActive { get; set; }
public Bus[] buses { get; set; }
}
class Bus
{
public int capacity { get; set; }
public string time { get; set; }
public string direction { get; set; }
}
class Program
{
static void Main(string[] args)
{
new DB("busroutes");
var routeA = new Route
{
name = "Route A",
buses = new Bus[]
{
new Bus { capacity = 15, direction = "Inbound", time = "8:00:00"},
new Bus { capacity = 25, direction = "Outbound", time = "9:00:00" },
new Bus { capacity = 35, direction = "Inbound", time = "10:00:00" }
}
};
routeA.Save();
var query = routeA.Collection()
.Where(r => r.ID == routeA.ID)
.SelectMany(r => r.buses);
Console.WriteLine(query.ToString());
var busesOfRouteA = query.ToArray();
foreach (var bus in busesOfRouteA)
{
Console.WriteLine(bus.time.ToString());
}
Console.ReadKey();
}
}
}