MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Como consultar um elemento relativo usando o MongoDB


Tudo sobre isso é bastante horrível, você não pode indexar em algo como os valores de "nome" e seu "caminho" para cada atributo varia em todos os lugares. Então isso é muito ruim para consultas.

Percebo que você mencionou estruturas "aninhadas" e ainda pode acomodar isso com uma proposta semelhante e algumas tags adicionais, mas quero que você considere este exemplo do tipo "lista telefônica":
{
    "phones": [
        {
           "type": "Home",
           "name" : "Jeff",
           "phone" : "123-123-1234"
        },
        {
           "type": "Work",
           "name" : "Jeff",
           "phone" : "123-123-1234"
        },
    ]
}

Como na verdade são subdocumentos em uma matriz, campos como "nome" sempre compartilham o mesmo caminho, portanto, você não apenas pode indexá-los (o que será bom para o desempenho), mas a consulta é muito básica:
db.collection({ "phones.name": "Jeff" })

Isso faz exatamente o que você precisa encontrando "Jeff" em qualquer entrada de "nome". Se você precisar de uma hierarquia, adicione alguns campos nesses subdocumentos para indicar o relacionamento pai/filho que você pode usar no pós-processamento. Ou mesmo como um caminho materializado que pode auxiliar suas consultas.

Realmente é a melhor abordagem.

Se você realmente deve manter esse tipo de estrutura, pelo menos faça algo assim com o JavaScript que vai sair da primeira partida em profundidade:
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;

  }
)

O formato existe uma notação abreviada para o $where operador, o que é uma péssima notícia para o desempenho, mas sua estrutura não oferece muitas outras opções. De qualquer forma, a função deve recorrer em cada documento aninhado até que o "campo" com o "valor" seja encontrado.

Para qualquer coisa de escala de produção, realmente procure mudar a estrutura para algo que possa ser indexado e acessado rapidamente. O primeiro exemplo deve lhe dar um ponto de partida. Confiar em JavaScript arbitrário para consultas como sua estrutura atual o restringe é uma má notícia.