#mongodb
#mongodb
Вопрос:
У меня есть эти коллекции:
Сайты
{
_id: ObjectId("5acdb8f65ea63a27c1facf86"),
TemplateId: ObjectId("sdfsdfs34234234sdf"),
}
Шаблоны
{
_id: ObjectId("sdfsdfs34234234sdf"),
Type: "Site",
Name: "Site 1",
Sections:[{
id: ObjectId("8asdf89asd8f9sdf"),
Header: "Header1",
FieldItems: [
{
FieldId: ObjectId("jsd32423423423"),
x: 1,
y: 0
},
{
FieldId: ObjectId("2342sdffafdasdfdfs"),
x: 1,
y: 1
}
]
},
(...more sections...)
]
}
Поля
{
_id: ObjectId("jsd32423423423"),
Type: "Phone",
Name: "Phone_Test"
},
{
_id: ObjectId("2342sdffafdasdfdfs"),
Type: "Numeric",
Name: "Number_Test"
}
Я новичок в MongoDB, но потратил пару дней на чтение вопросов и ответов, а также документации. Я использую MongoDB 4.2.6. Я пытаюсь вернуть результат, отформатированный следующим образом:
{
id: ObjectId("5acdb8f65ea63a27c1facf86"),
TemplateId: ObjectId("sdfsdfs34234234sdf"),
Template: {
id: ObjectId("sdfsdfs34234234sdf"),
Type: "Site",
Sections:[{
id: ObjectId("8asdf89asd8f9sdf"),
Header: "Header1",
FieldItems: [
{
FieldId: ObjectId("jsd32423423423"),
x: 1,
y: 0,
Field: {
_id: ObjectId("jsd32423423423"),
Type: "Phone",
Name: "Phone_Test"
}
}, (...)]
}]
}
Я написал агрегированный запрос с вложенными поисковыми системами, чтобы в основном попасть туда, но чтобы заставить его работать, мне пришлось развернуть разделы и элементы полей. Я не нашел способа привести массивы к тому, как я их хотел бы. Я пробовал группировать, но возникли проблемы с вложенными массивами. Я даже не уверен, что это лучший способ получить нужные мне результаты:
db.getCollection("AppSites").aggregate(
[
{
"$lookup" : {
"from" : "AppTemplates",
"let": {"template_id": "$TemplateId"},
"pipeline": [
{ "$match": { "$expr": { "$eq" : ["$_id", "$$template_id"] } } },
{ "$unwind": "$Sections"},
{ "$unwind": "$Sections.FieldItems"},
{
"$lookup": {
"from": "AppFields",
"let": {"field_id": "$Sections.FieldItems.FieldId"},
"pipeline": [
{ "$match": { "$expr": { "$eq": ["$_id", "$$field_id"] } } }
],
"as": "Sections.FieldItems.Field"
}
}
],
"as" : "Templates"
}
}
]
);
Ответ №1:
Вы сделали это $unwind
два раза, поэтому вам нужно использовать два $group
.
{
$group: {
_id: {
secId: "$_id",
fId: "$Sections.id"
},
Type: {
$first: "$Type"
},
Name: {
$first: "$Name"
},
Header: {
$first: "$Sections.Header"
},
fieldItems: {
$push: "$Sections.FieldItems"
}
}
},
{
$group: {
_id: "$_id.secId",
Type: {
$first: "$Type"
},
Name: {
$first: "$Name"
},
Sections: {
$push: {
id: "$_id.fId",
Header: "$Header",
fieldItems: "$fieldItems"
}
}
}
}
- Первая группа — для группировки дочерних объектов. Но тип, имя и заголовок должны быть установлены в родительский и дочерний массив соответственно.
- Вторая группа — для группировки родительских объектов. Мы получаем все отдельные поля при группировании дочерних. Здесь нам просто нужно настроить его в правильном порядке.
Рабочая игровая площадка Mongo
Примечание: При использовании $lookup
он предоставит массив. Но есть некоторые места, где вы просто создаете его как объект. Я не знаю, являются ли ваши соединения взаимно однозначными или нет. Если это так, вы можете использовать позиционный оператор в проекции или arrayElemAt