Como indexar atributos dinâmicos no MongoDB


8

Eu tenho o seguinte tipo de dados (simplificado um pouco do meu caso real) no MongoDB:

{
    "name":"some name",
    "attrs":[
        {"n":"subject","v":"Some subject"},
        {"n":"description","v":"Some great description"},
        {"n":"comments","v":"Comments are here!"},
        ]
}

O array attrs é um contêiner para atributos dinâmicos, ou seja, não sei de antemão que tipo de atributos são colocados lá. n significa nome e v significa valor.

O livro MongoDB In Action descreve isso como uma solução para ter atributos dinâmicos no caso em que os atributos são completamente imprevisíveis. Também descreve que você pode indexá-lo assim:

db.mycollection.ensureIndex({"attrs.n":1, "attrs.v":1})

As consultas podem ser feitas assim:

db.mycollection.find({attrs: {$elemMatch: {n: "subject", v: "Some subject"}}})

Quando eu testei isso, obtive um desempenho muito ruim. Testei com mycollection com 2 milhões de documentos e sem índice parece ter um desempenho melhor.

Então, a pergunta continua: existe uma maneira de indexar esse tipo de configuração de atributo dinâmico para que a indexação tenha um bom desempenho? No meu caso, não é possível ter apenas chaves como "assunto" e "descrição" e indexá-las todas ...

Respostas:


5

Também fiz essa mesma pergunta (de forma um pouco expandida) na lista de discussão mongodb-user , onde obtive uma resposta. Leia a partir daí para obter mais detalhes. A resposta curta é que a estratégia usada na pergunta deve funcionar bem, mas há um problema que a torna muito ineficiente. Felizmente, o problema será corrigido em breve.

No meu caso, só preciso consultar correspondências exatas para a tupla {n, v}, para que eu possa criar um índice multikey:

db.mycollection.ensureIndex({"attrs":1})

e faça com que eles consultem assim:

db.mycollection.find({"attrs": {n: "subject", v: "Some subject"}})

que funciona muito bem e usa o índice de maneira muito eficaz.


0

A mesma pergunta foi feita aqui . A partir da versão 4.2 do MongoDB, eles anunciaram índices curinga. Aqui está um exemplo:

db.myCollection.createIndex( { "subdocument.$**": 1 } );
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.