Ve verzích Modern MongoDB je nejúčinnějším způsobem jednoduše poznamenat pole pomocí existujících vlastností dokumentu. Přímý zápis polí byl zaveden v MongoDB 3.2:
db.collection.aggregate([
{ "$project": {
"lat": 1,
"long": 1,
"geometry": {
"type": { "$literal": "Point" },
"coordinates": [ "$lat", "$long" ]
}
}},
{ "$out": "newcollection" }
])
Nebo dokonce pomocí $addFields
jednoduše "připojit" novou vlastnost k dokumentům:
db.collection.aggregate([
{ "$addFields": {
"geometry": {
"type": { "$literal": "Point" },
"coordinates": [ "$lat", "$long" ]
}
}},
{ "$out": "newcollection" }
])
Pokud používáte MongoDB 2.6 a vyšší, můžete to udělat pomocí agregačního rámce a vyhnout se zacyklení výsledků ve vašem klientském programu za účelem vytvoření nové kolekce.
Hlavní funkcí, která vám pomůže, je $ ven
operátora pro odeslání výstupu do nové kolekce. Ale také být trochu chytrý, abyste vytvořili pole, které potřebujete.
db.collection.aggregate([
{ "$project": {
"lat": 1,
"long": 1,
"type": { "$literal": ["lat","long"] }
}},
{ "$unwind": "$type" },
{ "$group": {
"_id": "$_id",
"lat": { "$first": "$lat" },
"long": { "$first": "$long" },
"coordinates": {
"$push": {
"$cond": [
{ "$eq": [ "$type", "lat" ] },
"$lat",
"$long"
]
}
}
}},
{ "$project": {
"lat": 1,
"long": 1,
"geometry": {
"type": { "$literal": "Point" },
"coordinates": "$coordinates"
}
}},
{ "$out": "newcollection" }
])
Toto tedy využívá $literal
za účelem zadání nového pole na začátku potrubí. Tento operátor vloží obsah do vlastnosti dokumentu přesně jak se dodává. Nejsou tedy povoleny žádné substituce proměnných, tedy „doslovné“.
Abychom vytvořili pole "coordintes", jednoduše rozvineme první pole, které v podstatě vytvoří dva z každého dokumentu s jinou hodnotou v "type". To se pak použije ve $group
fáze podmíněně $push
buď hodnotu "$lat" nebo "$long" na toto pole.
Nakonec použijte $project
znovu pro dokončení struktury dokumentu a poté $out
odešle veškerý výstup do nové kolekce.
Všimněte si, že to má smysl pouze tehdy, pokud je vaším záměrem vytvořit novou kolekci a vyhnout se odesílání provozu „po drátě“. Toto nemohlo být použito čistě v rámci agregace k přetvoření vašeho dokumentu se záměrem poté provést „geo-prostorový“ dotaz ve stejném agregačním kanálu, protože „geo-prostorové“ dotazy budou fungovat pouze při skutečném indexování v kolekci. .
Takže vám to může pomoci vytvořit novou kolekci, jak chcete, ale alespoň to slouží jako příklad (nebo vlastně dva příklady), jak vytvořit pole z různých hodnot pomocí agregačního rámce.