Запрос глубоко вложенного объекта в массивах с использованием MongoDB и C# - PullRequest
2 голосов
/ 19 марта 2020

Я довольно новичок в MongoDB и уже сталкиваюсь с потным вызовом. Я пытаюсь получить элемент из массива с объектами внутри массива с объектами (если это имеет смысл). Вот как выглядит документ и что я пытаюсь получить:

https://i.imgur.com/W4Wfmhc.png

Итак, в основном структура выглядит следующим образом:

  • OptionMenus
    • OptionMenuSubject
      • OptionMenuItem

Чтобы получить OptionMenuItem, который я выбрал для его снятия, используя инструмент агрегации конвейера из инструмента MongoDB Compass

[{
    $unwind: {
        path: '$subjects'
    }
}, {
    $unwind: {
        path: '$subjects.items'
    }
}, {
    $project: {
        _id: '$subjects.items._id',
        item: '$subjects.items'
    }
}, {
    $match: {
        _id: ObjectId('5e6eaef8ae35a418f4f6dbd4')
    }
}]

Затем я попытался преобразовать это в C# безуспешно, насколько я понял:

        var optionMenuItem = await collection.Aggregate()
           .Unwind<OptionMenu, OptionMenuSubject>(i => i.Subjects)
           .Unwind<OptionMenuSubject, OptionMenuItem>(i => i.Items)
           .Match(i => i.Id == id)
           .ToListAsync();

Если кто-нибудь знает, что я делаю неправильно или как я могу это осуществить, было бы очень признательно:)

Ответы [ 2 ]

0 голосов
/ 22 марта 2020

Вот как я в конце концов решил это. Не моя самая гордая работа, потому что в ней нет строгой типизации, но она работает:

var collection = Database.GetCollection<BsonDocument>(_collectionName);    
var query = await collection.Aggregate()
                .Match(i => i["subjects.items._id"] == ObjectId.Parse(id))
                .Unwind(i => i["subjects"])
                .Unwind(i => i["subjects.items"])
                .Match(i => i["subjects.items._id"] == ObjectId.Parse(id))
                .ReplaceRoot(i => i["subjects.items"])
                .FirstOrDefaultAsync();
0 голосов
/ 19 марта 2020

раскручивать нефильтрованные данные не очень хорошая идея, потому что это создает много данных в памяти mongodb, и вы можете достичь предела конвейера агрегации 100 МБ. поэтому старайтесь всегда фильтровать и сужать записи, прежде чем раскручивать. я полагаю, что следующий конвейер даст нужный вам результат:

db.collection.aggregate([
    {
        $match: {
            'subjects.items._id': ObjectId('5e6eaef8ae35a418f4f6dbd4')
        }
    },
    {
        $unwind: '$subjects'
    },
    {
        $unwind: '$subjects.items'
    },
    {
        $match: {
            'subjects.items._id': ObjectId('5e6eaef8ae35a418f4f6dbd4')
        }
    },
    {
        $replaceWith: '$subjects.items'
    }
])

вот удобный способ выполнить этот конвейер с c#. Вы можете прочитать больше о том, как это работает здесь .

...