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

Insertar si no existe, de lo contrario eliminar MongoDB

Esa no es una buena manera de implementar votos positivos y negativos. Además de que el marco de agregación no es un mecanismo para actualizar documentos de ninguna manera, parece haber gravitado hacia pensar que puede ser una solución debido a la lógica que desea implementar. Pero el agregado no se actualiza.

Lo que quiere en su, bueno, llamémoslo un esquema de "pregunta" es una estructura como esta:

{
    "_id": ObjectId("53f51a844ffa9b02cf01c074"),
    "upvoted": [],
    "downvoted": [],
    "upvoteCount": 0,
    "downvoteCount": 0
}

Eso es algo que puede funcionar bien con actualizaciones atómicas y, de hecho, brindarle información detallada sobre el objeto al mismo tiempo.

Para las matrices "votadas a favor" y "votadas en contra", vamos a considerar que la votación de los "usuarios" tiene un valor ObjectId único similar. Entonces, lo que vamos a hacer es $push o $pull de cualquier matriz y también "incrementar/disminuir" los valores del contador junto con cada una de esas operaciones.

Así es como funciona esto para un voto a favor:

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "upvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
        "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075")
    },
    {         
        "$push": { "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "upvoteCount": 1, "downvoteCount": -1 },
        "$pull": { "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
    }
)

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "upvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
    },
    {
        "$push": { "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "upvoteCount": 1 },
    }
)

En realidad, son dos operaciones, que podría hacer con el AP de operaciones masivas Yo también (probablemente la mejor manera realmente) pero tiene un punto. La primera declaración solo coincidirá con un documento en el que el usuario actual tenga un "voto negativo" registrado en la matriz. Como tal, ya "empujamos" ese valor de identificación de usuario a la matriz de "votos negativos". Si no está allí, no se realiza ninguna actualización. Pero empuja y extrae de las respectivas matrices y también "incrementa/disminuye" los campos del contador al mismo tiempo.

Con la segunda declaración que solo coincidirá con algo donde la primera no lo hizo, hace una evaluación justa de que ahora no necesita tocar "votos negativos" y solo manejar los campos de votos positivos. En ambos casos, lo más seguro es asegurarse de que la condición principal sea que el valor de identificación de usuario actual no esté presente en la matriz "votada a favor".

Para los votos negativos, los campos se invierten:

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "downvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
        "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075")
    },
    {         
        "$pull": { "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "upvoteCount": -1, "downvoteCount": 1 },
        "$push": { "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
    }
)

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "downvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
    },
    {
        "$push": { "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "downvoteCount": 1 },
    }
)

Naturalmente, puede ver la progresión lógica para simplemente cancelar cualquier "voto positivo/negativo" para el usuario en cuestión. También puede ser inteligente al respecto si lo desea y exponer la información en su cliente para no solo mostrar si el usuario actual ya ha "votado a favor o en contra", sino también controlar las acciones de clic y eliminar las solicitudes innecesarias.