Quiero combinar $in con $split como en el siguiente ejemplo, pero no dice "$in necesita una matriz". Entiendo que la salida de $split es una matriz, así que no sé por qué falla. ¿Sabes cómo solucionarlo u otra forma de hacerlo? Gracias
db.mydoc.aggregate([ { '$match': { 'myid': { '$in': { '$split': [ '136618,136620,136622', ',', ], }, }, }, }, { '$project': { ... }, }, ]);Este "fallo" es el comportamiento esperado, entendamos por qué.
Primero debemos echar un vistazo al comportamiento de $match como se especifica en los documentos:
$match toma un documento que especifica las condiciones de consulta. La sintaxis de consulta es idéntica a la sintaxis de consulta de operación de lectura; es decir, $match no acepta expresiones de agregación sin procesar. En su lugar, utilice una expresión de consulta $expr para incluir una expresión de agregación en $match.
Esto significa que cuando usa $match , usa el lenguaje de consulta de forma predeterminada, ahora el "problema" proviene de la diferencia entre los dos operadores $in , el operador $in de consulta (que se está utilizando) y el operador $in de agregación (que usted supongamos que se está utilizando).
Es cierto que $split resuelve en una matriz. pero $split también es un operador de agregación, ahora creo que este caso debería arrojar un error, pero por alguna razón, como mencionaste, este comportamiento simplemente se resuelve sin resultados. sin embargo, el operador $in agregación acepta expresiones de agregación sin procesar.
Esto significa que todo lo que tiene que hacer es convertir su consulta $match para usar $expr para que pueda usar la versión agregada de $in dentro de la coincidencia, así:
db.collection.aggregate([ { "$match": { $expr: { $in: [ "$myid", { "$split": [ "136618,136620,136622", "," ] } ] } } } ])@Tom Slabbaert dio una respuesta muy completa y buena. Solo para completar, una solución alternativa (si trabaja con Javascript/Mongo Shell) es esta:
db.mydoc.aggregate([ { '$match': { 'myid': { '$in': '136618,136620,136622'.split(',') } } }, { '$project': { ... }, }, ]); Tenga en cuenta que cualquiera de las soluciones crea una matriz de cadenas, es decir, [ "136618", "136620", "136622" ] . No coincide si su colección tiene valores numéricos, por ejemplo, { myid: 136618 }
Puedes utilizar
'136618,136620,136622'.split(',').map(x => NumberInt(x))o
{ $map: { input: { "$split": ["136618,136620,136622", ","] }, in: { $toInt: "$$this" } } }