#mongodb #aggregation-framework #doctrine-odm
#mongodb #платформа агрегации #doctrine-odm
Вопрос:
Я сделал несколько поисковых запросов перед публикацией, но в настоящее время я столкнулся с проблемой. Я работаю с Mongo 4 с Symfony4 и Mongo-odm. Мне нужно исправить мой запрос оболочки, тогда я адаптирую его к doctrine-odm.
У меня есть две подобные коллекции :
схема :
{
"_id" : "5c6e6f7be05bd900a1682582",
"name" : "Awesome name",
"startDate" : ISODate("2019-02-13T05:48:24.000Z"),
"endDate" : ISODate("2019-02-13T12:30:50.000Z"),
"state" : "closed",
"type" : "I",
"agency" : "5c6cfe7ae05bd9007477f7ee",
"drivers" : [
"5c6cfe99e05bd90074783c99",
"5c6cfe99e05bd90074784d85",
],
"exportedAt" : ISODate("2019-02-13T12:32:02.000Z"),
"createdAt" : ISODate("2019-02-21T09:29:31.783Z"),
"updatedAt" : ISODate("2019-02-21T09:29:31.783Z"),
"messages" : [
"5c6e7125e05bd900a1683595",
"5c6e7125e05bd900a1683596",
"5c6e7125e05bd900a1683597",
"5c6e7126e05bd900a1683598"
],
"orders" : [
"5c6d0269e05bd900747a559c",
"5c6d0269e05bd900747a559c",
"5c6d0269e05bd900747a559c"
]
}
порядок :
{
"_id" : "5c6d04a9e05bd900747a7c40",
"startDate" : ISODate("2019-02-19T08:35:04.000Z"),
"endDate" : ISODate("2019-02-19T12:53:50.000Z"),
"state" : "closed",
"company" : 1982,
"weight" : 960.0,
"type" : "E",
"circuit" : "5c6d0307e05bd900747a6c39",
"agency" : "5c6cfe79e05bd9007477f580",
"client" : "5c6d0074e05bd9007479a7c1",
"createdAt" : ISODate("2019-02-20T19:45:54.392Z"),
"updatedAt" : ISODate("2019-02-20T19:45:54.392Z"),
}
Из схемы я хочу получить документы заказов вместо их идентификатора.
Я пробовал запрашивать подобным образом :
db.circuit.aggregate([
{ "$match":
{ "agency":
{ "$in":
[
"5c6cfe79e05bd9007477f559", "5c6cfe79e05bd9007477f55b", "5c6cfe79e05bd9007477f562", "5c6cfe79e05bd9007477f563", "5c6cfe79e05bd9007477f565",
"5c6cfe79e05bd9007477f566", "5c6cfe79e05bd9007477f57e", "5c6cfe79e05bd9007477f57f", "5c6cfe79e05bd9007477f580", "5c6cfe79e05bd9007477f582",
"5c6cfe79e05bd9007477f587", "5c6cfe79e05bd9007477f588", "5c6cfe79e05bd9007477f589", "5c6cfe79e05bd9007477f58a", "5c6cfe79e05bd9007477f590",
"5c6cfe79e05bd9007477f591", "5c6cfe79e05bd9007477f592", "5c6cfe79e05bd9007477f593", "5c6cfe79e05bd9007477f594", "5c6cfe79e05bd9007477f595",
"5c6cfe79e05bd9007477f596", "5c6cfe79e05bd9007477f59b", "5c6cfe79e05bd9007477f59c", "5c6cfe79e05bd9007477f5af", "5c6cfe79e05bd9007477f5b2",
"5c6cfe79e05bd9007477f5e5", "5c6cfe79e05bd9007477f66d", "5c6cfe79e05bd9007477f679"
]
}
}
},
{
"$lookup":
{
"from": "agency",
"localField": "agency",
"foreignField": "_id",
"as": "agency"
}
},
{"$unwind": "$agency"},
{
"$lookup":
{
"from": "order",
"localField": "orders",
"foreignField": "_id",
"as": "sub_orders"
}
},
{
$unwind: {
path: "$sub_orders",
preserveNullAndEmptyArrays: true
}
},
{
"$project":
{
"name": "$$ROOT.nom",
"startDate": "$$ROOT.startDate",
"endDate": "$$ROOT.endDate",
"state": "$$ROOT.state",
"type": "$$ROOT.type",
"agencyName": "$agency.name",
"sub_orders": "$sub_orders"
}
}
]);
К сожалению, я просто извлекаю первый документ из массива id подобных заказов :
{
"_id" : "5c6e6f9ee05bd900a168268f",
"name" : "Circuit",
"startDate" : ISODate("2019-02-13T06:18:28.000Z"),
"endDate" : ISODate("2019-02-13T11:40:12.000Z"),
"state" : "closed",
"type" : "I",
"agencyName" : "Amazing Agency",
"sub_orders" : {
"_id" : "5c6d04a9e05bd900747a7c40",
"startDate" : ISODate("2019-02-19T08:35:04.000Z"),
"endDate" : ISODate("2019-02-19T12:53:50.000Z"),
"state" : "closed",
"company" : 1982,
"weight" : 960.0,
"type" : "E",
"circuit" : "5c6d0307e05bd900747a6c39",
"agency" : "5c6cfe79e05bd9007477f580",
"client" : "5c6d0074e05bd9007479a7c1",
"createdAt" : ISODate("2019-02-20T19:45:54.392Z"),
"updatedAt" : ISODate("2019-02-20T19:45:54.392Z"),
}
}
Однако я хочу получить столько документов заказа, сколько идентификаторов в массиве идентификаторов, таких как :
{
"_id" : "5c6e6f9ee05bd900a168268f",
"name" : "Circuit",
"startDate" : ISODate("2019-02-13T06:18:28.000Z"),
"endDate" : ISODate("2019-02-13T11:40:12.000Z"),
"state" : "closed",
"type" : "I",
"agencyName" : "Amazing Agency",
"sub_orders" : {
"_id" : "5c6d04a9e05bd900747a7c40",
"startDate" : ISODate("2019-02-19T08:35:04.000Z"),
"endDate" : ISODate("2019-02-19T12:53:50.000Z"),
"state" : "closed",
"company" : 1982,
"weight" : 960.0,
"type" : "E",
"createdAt" : ISODate("2019-02-20T19:45:54.392Z"),
"updatedAt" : ISODate("2019-02-20T19:45:54.392Z"),
},{
"_id" : ".....",
"startDate" : ISODate("2019-02-19T08:35:04.000Z"),
"endDate" : ISODate("2019-02-19T12:53:50.000Z"),
"state" : "closed",
"company" : 1982,
"weight" : 960.0,
"type" : "E",
"createdAt" : ISODate("2019-02-20T19:45:54.392Z"),
"updatedAt" : ISODate("2019-02-20T19:45:54.392Z"),
},{
"_id" : ".....",
"startDate" : ISODate("2019-02-19T08:35:04.000Z"),
"endDate" : ISODate("2019-02-19T12:53:50.000Z"),
"state" : "closed",
"company" : 1982,
"weight" : 960.0,
"type" : "E",
"createdAt" : ISODate("2019-02-20T19:45:54.392Z"),
"updatedAt" : ISODate("2019-02-20T19:45:54.392Z"),
}
}
Спасибо, что спасли меня! 🙂
Комментарии:
1. Привет, кажется, что $ lookup выполняет addToSet для размещения элементов в массиве, но не может найти никакой информации в документе. Попробуйте использовать разные orders _id в вашем документе схемы, вы увидите несколько заказов в результате sub_orders.
2. Спасибо за ответ, я пробовал со многими другими идентификаторами и ссылался на коллекции, такие как драйверы, но то же самое.
Ответ №1:
Мне удалось сделать то, что я хотел, со следующим запросом, это занимает у меня несколько часов … 🙂
db.circuit.aggregate([
{ "$match":
{ "agency":
{ "$in":
[
"5c6cfe79e05bd9007477f559", "5c6cfe79e05bd9007477f55b", "5c6cfe79e05bd9007477f562", "5c6cfe79e05bd9007477f563", "5c6cfe79e05bd9007477f565",
"5c6cfe79e05bd9007477f566", "5c6cfe79e05bd9007477f57e", "5c6cfe79e05bd9007477f57f", "5c6cfe79e05bd9007477f580", "5c6cfe79e05bd9007477f582",
"5c6cfe79e05bd9007477f587", "5c6cfe79e05bd9007477f588", "5c6cfe79e05bd9007477f589", "5c6cfe79e05bd9007477f58a", "5c6cfe79e05bd9007477f590",
"5c6cfe79e05bd9007477f591", "5c6cfe79e05bd9007477f592", "5c6cfe79e05bd9007477f593", "5c6cfe79e05bd9007477f594", "5c6cfe79e05bd9007477f595",
"5c6cfe79e05bd9007477f596", "5c6cfe79e05bd9007477f59b", "5c6cfe79e05bd9007477f59c", "5c6cfe79e05bd9007477f5af", "5c6cfe79e05bd9007477f5b2",
"5c6cfe79e05bd9007477f5e5", "5c6cfe79e05bd9007477f66d", "5c6cfe79e05bd9007477f679"
]
}
},
},
{
"$match":
{ "date": { "$lte": ISODate("2019-02-13T12:32:02.000Z") } }
},
{"$match":
{ "date": { "$gte": ISODate("2019-02-11T12:32:02.000Z") } }
},
{
"$lookup":
{
"from": "agency",
"localField": "agency",
"foreignField": "_id",
"as": "agency"
}
},
{"$unwind": "$agency"},
{
"$lookup":
{
"from": "order",
"localField": "orders",
"foreignField": "_id",
"as": "orders"
}
},
{ "$unwind": "$orders" },
{
"$lookup":
{
"from": "driver",
"localField": "drivers",
"foreignField": "_id",
"as": "drivers"
}
},
{ "$unwind": "$drivers" },
{ "$unwind": "$camions" },
{
"$group": {
"_id": "$_id",
"orders": { "$addToSet": "$orders" },
"drivers": { "$last": "$drivers" },
"agency": { "$addToSet": "$agency" },
"type": { "$addToSet": "$type" },
"state": { "$addToSet": "$state" },
"date": { "$addToSet": "$date" }
}
},
{ "$unwind": "$agency" },
{ "$unwind": "$date" },
{ "$unwind": "$type" },
{ "$unwind": "$state" }
{
"$project":
{
"unloaded_orders": {
$filter: {
input: '$orders',
as: 'o',
cond: { $eq: ['$$o.state', 'unloaded'] }
}
},
"unclosed_orders": {
$filter: {
input: '$orders',
as: 'o',
cond: { $in: ['$$o.state', ['added', 'edited', 'started']] }
}
},
"closed_orders": {
$filter: {
input: '$orders',
as: 'o',
cond: { $eq: ['$$o.state', 'closed'] }
}
},
"agency": "$agency",
"date": "$date",
"state": "$state",
"type": "$type",
"drivers": "$drivers"
}
}
]);
Надеюсь, это могло бы кому-то помочь 🙂
Комментарии:
1. Было ли это необходимо с doctrine-odm? Если вы правильно аннотируете (или сопоставляете) свои ссылки, doctrine-odm правильно увлажнит ваши классы. Выполнение
$circuit->getOrders();
автоматически выполнит агрегацию, чтобы вернуть массивOrders
документов, которые связаны сCircuit $cricuit
.