sql >> Base de Datos >  >> NoSQL >> MongoDB

Cómo crear un nuevo campo de matriz con el marco agregado

En las versiones modernas de MongoDB, la forma más eficiente es simplemente anotar la matriz utilizando las propiedades del documento existente. La notación directa de matrices se introdujo en MongoDB 3.2:

db.collection.aggregate([
  { "$project": {
    "lat": 1,
    "long": 1,
    "geometry": {
      "type": { "$literal": "Point" },
      "coordinates": [ "$lat", "$long" ]
    }
  }},
  { "$out": "newcollection" }
])

O incluso usando $addFields para simplemente "añadir" la nueva propiedad a los documentos:

db.collection.aggregate([
  { "$addFields": {
    "geometry": {
      "type": { "$literal": "Point" },
      "coordinates": [ "$lat", "$long" ]
    }
  }},
  { "$out": "newcollection" }
])

Si está utilizando MongoDB 2.6 y superior, puede hacerlo con el marco de agregación y evitar los resultados en bucle en su programa cliente para crear una nueva colección.

La característica principal aquí que lo ayuda es el $out operador para enviar la salida a una nueva colección. Pero también ser un poco inteligente para crear la matriz que necesita.

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" }
])

Esto hace uso de $literal operador para especificar una nueva matriz en la cabeza de la canalización. Este operador pondrá contenido en la propiedad del documento exactamente como se suministra. Por lo tanto, no se permiten sustituciones de variables, por lo tanto, "literal".

Para crear la matriz de "coordenadas", simplemente desenrollamos esa primera matriz que esencialmente crea dos de cada documento con un valor diferente en "tipo". Esto luego se usa en el $group etapa para condicionalmente $push ya sea el valor "$lat" o "$long" en esa matriz.

Finalmente use $project nuevamente para finalizar la estructura del documento y luego $out envía toda la salida a la nueva colección.

Tenga en cuenta que esto solo tiene sentido si su intención es crear una nueva colección y evitar enviar tráfico "por cable". Esto no podría usarse únicamente dentro del marco de agregación para remodelar su documento con la intención de luego hacer una consulta "geoespacial" en esa misma canalización de agregación, ya que las consultas "geoespaciales" solo funcionarán cuando realmente estén indexadas en una colección. .

Entonces, esto puede ayudarlo a crear una nueva colección como desee, pero al menos sirve como ejemplo (o dos ejemplos en realidad) de cómo crear una matriz a partir de diferentes valores con el marco de agregación.