Учитывая следующую фиктивную коллекцию, я хочу выделить страны-экспортеры и импортеры для данного ресурса:
[{
country: "France",
exchange: {
export: [{
resource: "MILK",
origin: ["Toulouse", "Bordeaux"]
}],
import: [{
resource: "BEEF",
origin: ["Lyon", "Marseille"]
}]
}
}, {
country: "Spain",
exchange: {
export: [{
resource: "PORK",
origin: ["Madrid", "Barcelona"]
}],
import: [{
resource: "MILK",
origin: ["Valencia", "Bilbao"]
}]
}
}]
Ожидаемый результат:
{
resource: "MILK",
exportingCountries: ["France"],
importingCountries: ["Spain"]
}
Я играл с $group
, но не могу найти способ условно $addToSet
стран.
Вы можете использовать $concatArrays для объединения массивов exchange.export
и exchange.import
. Это позволяет вам $ группа с помощью country
, а затем вам нужно вернуться import
и export
с помощью операторов $фильтр и $карта, попробуйте:
db.col.aggregate([
{
$project: {
country: 1,
resources: {
$concatArrays: [
{ $map: { input: "$exchange.export", in: { resource: "$$this.resource", exchange: "export" } } },
{ $map: { input: "$exchange.import", in: { resource: "$$this.resource", exchange: "import" } } },
]
}
}
},
{
$unwind: "$resources"
},
{
$group: {
_id: "$resources.resource",
resources: { $addToSet: { country: "$country", exchange: "$resources.exchange" } }
}
},
{
$project: {
_id: 0,
resource: "$_id",
importingCountries: {
$map: {
input: { $filter: { input: "$resources", as: "r", cond: { $eq: [ "$$r.exchange", "import" ] } } },
in: "$$this.country"
}
},
exportingCountries: {
$map: {
input: { $filter: { input: "$resources", as: "r", cond: { $eq: [ "$$r.exchange", "export" ] } } },
in: "$$this.country"
}
}
}
}
])
Выход:
{ "resource" : "PORK", "importingCountries" : [ ], "exportingCountries" : [ "Spain" ] }
{ "resource" : "BEEF", "importingCountries" : [ "France" ], "exportingCountries" : [ ] }
{ "resource" : "MILK", "importingCountries" : [ "Spain" ], "exportingCountries" : [ "France" ] }
это работает, хотя для этого требуется добавить
$match
для фильтрации выходного ресурса. Спасибо !