Saltar al contenido

Agregación de MongoDB: coincide con el valor en la matriz

Solución:

Como se dijo, $where es una buena opción en la que no es necesario continuar con la lógica en la canalización de agregación.

Pero si lo hace, use $redact, con $map para transformar el “valor” en una matriz y el uso de $setIsSubSet comparar. Es la forma más rápida de hacer esto, ya que no necesita duplicar documentos usando $unwind:

db.collection.aggregate([
   { "$redact": {
       "$cond": {
           "if": { "$setIsSubset": [
                { "$map": {
                    "input": { "$literal": ["A"] },
                    "as": "a",
                    "in": "$value"
                }},
                "$array"
           ]},
           "then": "$$KEEP",
           "else": "$$PRUNE"
       }
   }}
])

El $redact El operador de tubería permite el procesamiento de una condición lógica dentro de $cond y utiliza las operaciones especiales $$KEEP para “mantener” el documento donde la condición lógica es verdadera o $$PRUNE para “eliminar” el documento donde la condición era falsa.

Esto le permite funcionar como $project con una subsecuente $match, pero en una sola etapa de pipeline que es más eficiente.

Teniendo en cuenta que se trata de operadores codificados nativos y no de JavaScript, es probable que sea “la” forma más rápida de realizar su coincidencia. Entonces, siempre que esté utilizando una versión de MongoDB 2.6 o superior, esta es la forma en que debe hacerlo para comparar estos elementos en su documento.

Puede utilizar la expresión de agregación en una consulta regular en la versión 3.6.

db.collection_name.find({"$expr": {"$in": ["$value", "$array"]}})

Usando agregación:

Puedes usar $match + $expr en corriente 3.6 versión.

db.collection_name.aggregate({"$match": {"$expr": {"$in": ["$value", "$array"]}}})

Puedes probar $redact + $in expresión en 3.4 versión.

db.collection_name.aggregate({
  "$redact": {
    "$cond": [
      {
        "$in": [
          "$value",
          "$array"
        ]
      },
      "$$KEEP",
      "$$PRUNE"
    ]
  }
})

Una ligera variación basada en la respuesta de @ chridam:

db.test.aggregate([
    { "$unwind": "$array" },
    { "$group": {
                  _id: { "_id": "$_id", "value": "$value" },
                  array: { $push: "$array" },
                  mcount: { $sum: {$cond: [{$eq: ["$value","$array"]},1,0]}}
                }
    },
    { $match: {mcount: {$gt: 0}}},
    { "$project": { "value": "$_id.value", "array": 1, "_id": 0 }}
])

La idea es $unwind y $group retrocede la matriz, contando en mcount el número de elementos que coinciden con el valor. Después de eso, un simple $match en mcount > 0 filtrará los documentos no deseados.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *