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

MongoDB:busque documentos con valores de campo dados en un objeto con una clave desconocida

Aunque parece que se ha acercado a esta estructura debido a un problema con las actualizaciones en el uso de matrices anidadas, en realidad solo ha causado otro problema al hacer otra cosa que no es realmente compatible, y es que no hay "comodín" concepto para buscar claves no especificadas utilizando los operadores de consulta estándar que son óptimos.

La única forma en que realmente puede buscar dichos datos es usando código JavaScript en el servidor para atravesar las claves usando $where . Claramente, esta no es una muy buena idea, ya que requiere fuerza bruta evaluación en lugar de usar cosas útiles como un índice, pero se puede abordar de la siguiente manera:

db.theses.find(function() {
    var relations = this.relations;
    return Object.keys(relations).some(function(rel) {
        return relations[rel].type == "interpretation";
    });
))

Si bien esto devolverá los objetos de la colección que contienen el valor anidado requerido, debe inspeccionar cada objeto de la colección para realizar la evaluación. Esta es la razón por la cual dicha evaluación solo debería usarse cuando se combina con algo que puede usar directamente un índice en lugar de un valor duro del objeto en la colección.

Aún así, la mejor solución es considerar remodelar los datos para aprovechar los índices en la búsqueda. Cuando sea necesario actualizar la información de "calificaciones", básicamente "aplanar" la estructura para considerar cada elemento de "calificación" como la única matriz de datos en su lugar:

{
    "_id": "aeokejXMwGKvWzF5L",
    "text": "test",
    "relationsRatings": [
        {
            "relationId": "cF6iKAkDJg5eQGsgb",
            "type": "interpretation",
            "originId": "uFEjssN2RgcrgiTjh",
            "ratingId": 1,
            "ratingScore": 5
        },
        {
            "relationId": "cF6iKAkDJg5eQGsgb",
            "type": "interpretation",
            "originId": "uFEjssN2RgcrgiTjh",
            "ratingId": 2,
            "ratingScore": 6
        }
   ]
}

Ahora, la búsqueda es, por supuesto, bastante simple:

db.theses.find({ "relationsRatings.type": "interpretation" })

Y, por supuesto, el posicional $ El operador ahora se puede usar con la estructura más plana:

db.theses.update(
    { "relationsRatings.ratingId": 1 },
    { "$set": { "relationsRatings.$.ratingScore": 7 } }
)

Por supuesto, esto significa la duplicación de los datos "relacionados" para cada valor de "calificación", pero este es generalmente el costo de actualizar por posición coincidente, ya que esto es todo lo que se admite con un solo nivel de anidamiento de matriz solamente.

Por lo tanto, puede forzar la lógica para que coincida con la forma en que la tiene estructurada, pero no es una buena idea hacerlo y provocará problemas de rendimiento. Sin embargo, si su principal necesidad aquí es actualizar la información de "calificaciones" en lugar de simplemente agregarla a la lista interna, entonces una estructura más plana será de mayor beneficio y, por supuesto, será mucho más rápido para buscar.