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

Cómo consultar un elemento relativo usando MongoDB

Todo acerca de esto es bastante horrible, no es posible indexar algo como los valores de "nombre" y su "ruta" a cada atributo variará en todas partes. Así que esto es realmente malo para las consultas.

Noté que menciona estructuras "anidadas", y aún podría acomodar esto con una propuesta similar y algunas etiquetas adicionales, pero quiero que considere este ejemplo de tipo "guía telefónica":

{
    "phones": [
        {
           "type": "Home",
           "name" : "Jeff",
           "phone" : "123-123-1234"
        },
        {
           "type": "Work",
           "name" : "Jeff",
           "phone" : "123-123-1234"
        },
    ]
}

Dado que en realidad se trata de subdocumentos dentro de una matriz, los campos como "nombre" siempre comparten la misma ruta, por lo que no solo puede indexarlos (lo que será bueno para el rendimiento), sino que la consulta es muy básica:

db.collection({ "phones.name": "Jeff" })

Eso hace exactamente lo que necesita al encontrar "Jeff" en cualquier entrada de "nombre". Si necesita una jerarquía, agregue algunos campos en esos subdocumentos para indicar la relación padre/hijo que puede usar en el procesamiento posterior. O incluso como un camino materializado que podría ayudar a sus consultas.

Realmente es el mejor enfoque.

Si realmente debe mantener este tipo de estructura, al menos haga algo como esto con el JavaScript que se recuperará en la primera coincidencia en profundidad:

db.collection.find(
  function () {
    var found = false;

    var finder = function( obj, field, value ) {
      if ( obj.hasOwnProperty(field) && obj[field] == value )
        found = true;

      if (found) return true;

      for( var n in obj ) {
        if ( Object.prototype.toString.call(obj[n]) === "[object Object]" ) {
          finder( obj[n], field, value );
          if (found) return true;
        }
      }

    };

    finder( this, "name", "Jeff" );
    return found;

  }
)

El formato allí es una notación abreviada para $where operador, que es una mala noticia para el rendimiento, pero su estructura no ofrece muchas otras opciones. En cualquier caso, la función debe repetirse en cada documento anidado hasta que se encuentre el "campo" con el "valor".

Para cualquier cosa de escala de producción, realmente busque cambiar la estructura a algo que se pueda indexar y acceder rápidamente. El primer ejemplo debería darle un punto de partida. Confiar en JavaScript arbitrario para las consultas como lo limita su estructura actual es una mala noticia.