Я пытаюсь создать следующие методы для извлечения массива ObjectId из дочернего массива.
GetStorageLocationIds()
GetStorageRoomIds(ObjectId locationId)
GetStorageSectionIds(ObjectId locationId, ObjectId roomId)
GetStorageShelfIds(ObjectId locationId, ObjectId roomId, ObjectId sectionId)
GetStorageSlotIds(ObjectId locationId, ObjectId roomId, ObjectId sectionId, ObjectId shelfId)
(это может быть не так сложно, поскольку это уже массив ObjectId)
Каждый метод должен возвращать IEnumerable<ObjectId>
, содержащиймассив свойства id
соответствующего массива.Я понимаю, что мог бы просто получить весь документ для каждого списка, но я бы предпочел более эффективное и элегантное решение с использованием драйвера MongoDB c #.
Это пример документа:
{
"_id" : ObjectId("5cb2271a4bd93c0dec4db163"),
...
"StorageRooms" : [
{
"_id" : ObjectId("5cb49adc36ad6719bf947103"),
...
"StorageSections" : [ ]
},
{
"_id" : ObjectId("5cb49afa36ad6719bf947106"),
...
"StorageSections" : [
{
"_id" : ObjectId("5cb49bb8c40cd319cb2511ae"),
...
"StorageShelves" : [ ]
},
{
"_id" : ObjectId("5cb49bb8c40cd319cb2511af"),
...
"StorageShelves" : [
{
"_id" : ObjectId("5cb49bfe8d259019d9207f48"),
...
"StorageSlotIds" : [ ]
},
{
"_id" : ObjectId("5cb49bfe8d259019d9207f49"),
...
"StorageSlotIds" : [ ]
}
]
}
]
},
{
"_id" : ObjectId("5cb49afa36ad6719bf947107"),
...
"StorageSections" : [ ]
}
]
}
Вышеуказанные методы должны возвращать следующий массив, используя приведенный выше пример документа в качестве входных данных.(при условии, что он единственный в коллекции):
GetStorageLocationIds()
-> ["5cb2271a4bd93c0dec4db163"]
GetStorageRoomIds("5cb2271a4bd93c0dec4db163")
-> ["5cb49adc36ad6719bf947103,"5cb49afa36ad6719bf947106", "5cb49afa36ad6719bf947107"]
GetStorageSectionIds("5cb49afa36ad6719bf947106")
-> ["5cb49bb8c40cd319cb2511ae","5cb49bb8c40cd319cb2511af"]
и т. Д.
До сих пор я смог написать первый: GetStorageLocationIds
.Этот код, кажется, работает хорошо:
public async Task<IEnumerable<ObjectId>> GetAllDocumentIdsAsync(string database, string collection,
CancellationToken cancellationToken)
{
return (await _mongoContext.MongoClient.GetDatabase(database).GetCollection<T>(collection)
.Find(new BsonDocument())
.Project(new BsonDocument {{"_id", 1}})
.ToListAsync(cancellationToken)).Select(x => x[0].AsObjectId);
}
Когда дело доходит до следующего, я пытался использовать ProjectionDefinition
, но все, что он делал, это возвращал документ id
вместо каждого id
вмассив StorageRooms
.
public async Task<IEnumerable<ObjectId>> GetStorageRoomIdsAsync(ObjectId id, CancellationToken cancellationToken)
{
var filter = Builders<StorageLocation>.Filter.And(
Builders<StorageLocation>.Filter.Where(location => location.Id == id));
var projectionDefinition = Builders<StorageLocation>.Projection.Include(location => location.StorageRooms);
var projectionResult = await ProjectAsync(filter, projectionDefinition, cancellationToken);
return projectionResult.Select(x => x[0].AsObjectId);
}
После некоторых попыток использования агрегации, я считаю, что он будет работать с Unwind
, но я заблудился, как правильно реализовать это в c #.Заранее благодарим за любую помощь.
Редактировать Примечание: ObjectId и string в этом вопросе используются для краткости взаимозаменяемо.Я использую AutoMapper для моего реального проекта
Редактировать 2:
Ответ от Мики работал на GetStorageRoomIds
.Я сейчас пытаюсь использовать следующий код для GetStorageSectionIds
, но получаю ошибку:
return from location in AsQueryable()
where location.Id == id
from room in location.StorageRooms
where room.Id == roomId
from section in room.StorageSections
select section.Id;
Ошибка здесь