Вы можете получить уникальное целое число, назначенное каждому в одной агрегации, используя $facet
, чтобы сохранить исходные документы, используя $addToSet
, чтобы получить список уникальных адресов, и $indexOfArray
, чтобы присвоить значение каждому документу :
db.collection.aggregate([
{$facet: {
docs: [{$match: {}}],
addresses: [
{$group: {
_id: null,
address: {$addToSet: "$address"}
}}
]
}},
{$unwind: "$docs"},
{$unwind: "$addresses"},
{$addFields: {
"address.id": {
$indexOfArray: [
"$addresses.address",
"$docs.address"
]
}
}},
{$replaceRoot:{newRoot:"$docs"}},
{$out:"new_collection"}
])
Игровая площадка
Если вы предпочитаете ObjectId, у вас есть правильная идея, одна агрегация для вывода уникальных адресов во временную коллекцию, чтобы каждый был автоматически -назначен _id, а затем вторая агрегация для внедрения этих значений _id в исходные документы. В этом примере я собрал _id исходного документа, чтобы упростить последующий поиск.
db.collection.aggregate([
{$group:{
_id:"$address",
ids:{$push:"$_id"}
}},
{$project:{
address:"$_id",
ids:1,
_id:0
}},
{$out: "temp_address_collection"}
])
Детская площадка
db.collection.aggregate([
{$lookup:{
from:"temp_address_collection",
localField:"_id",
foreignField:"ids",
as: "matched"
}},
{$addFields:{matched:{$arrayElemAt:["$matched",0]}}},
{$addFields:{"$address.id": "$matched._id"}},
{$project:{matched:0}},
{$out:"new_collection"}
])
Детская площадка