W wydaniach Modern MongoDB najbardziej efektywnym sposobem jest po prostu zapisanie tablicy przy użyciu istniejących właściwości dokumentu. Bezpośrednia notacja tablic została wprowadzona w MongoDB 3.2:
db.collection.aggregate([
{ "$project": {
"lat": 1,
"long": 1,
"geometry": {
"type": { "$literal": "Point" },
"coordinates": [ "$lat", "$long" ]
}
}},
{ "$out": "newcollection" }
])
Lub nawet używając $addFields
aby po prostu "dołączyć" nową właściwość do dokumentów:
db.collection.aggregate([
{ "$addFields": {
"geometry": {
"type": { "$literal": "Point" },
"coordinates": [ "$lat", "$long" ]
}
}},
{ "$out": "newcollection" }
])
Jeśli używasz MongoDB 2.6 i nowszych, możesz to zrobić za pomocą struktury agregacji i uniknąć zapętlania wyników w programie klienckim w celu utworzenia nowej kolekcji.
Główną funkcją, która Ci pomoże, jest $ out
operator do wysyłania danych wyjściowych do nowej kolekcji. Ale także trochę sprytny, aby stworzyć tablicę, której potrzebujesz.
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" }
])
Wykorzystuje to $literal
operatora w celu określenia nowej tablicy na początku potoku. Ten operator umieści treść we właściwości dokumentu dokładnie jak jest dostarczany. Dlatego żadne podstawienia zmiennych nie są dozwolone, stąd „dosłowne”.
Aby utworzyć tablicę „coordintes”, po prostu rozwijamy pierwszą tablicę, która zasadniczo tworzy dwa z każdego dokumentu z inną wartością w „type”. Jest to następnie używane w $group
etap do warunkowego $push
wartość "$lat" lub "$long" w tej tablicy.
Na koniec użyj $project
ponownie, aby sfinalizować strukturę dokumentu, a następnie $out
wysyła wszystkie dane wyjściowe do nowej kolekcji.
Pamiętaj, że ma to sens tylko wtedy, gdy Twoim zamiarem jest utworzenie nowej kolekcji i uniknięcie wysyłania ruchu „przez sieć”. Nie można tego użyćwyłącznie w ramach agregacji do zmiany kształtu dokumentu z zamiarem wykonania zapytania „geoprzestrzennego” w tym samym potoku agregacji, ponieważ zapytania „geoprzestrzenne” będą działać tylko wtedy, gdy są faktycznie indeksowane w kolekcji .
Może to pomóc w stworzeniu nowej kolekcji, jak chcesz, ale przynajmniej służy jako przykład (lub dwa przykłady) tego, jak utworzyć tablicę z różnych wartości za pomocą struktury agregacji.