Pregunta

Quiero regex buscar un valor entero en MongoDB. ¿Es esto posible?

Estoy construyendo una interfaz de tipo CRUD que permite * para comodines en los diversos campos. Estoy tratando de mantener la interfaz de usuario consistente para algunos campos que son números enteros.

Considere lo siguiente:

> db.seDemo.insert({ "example" : 1234 });
> db.seDemo.find({ "example" : 1234 });
{ "_id" : ObjectId("4bfc2bfea2004adae015220a"), "example" : 1234 }
> db.seDemo.find({ "example" : /^123.*/ });
> 

Como se puede ver, insertar un objeto y yo soy capaz de encontrarlo por el valor. Si trato de una expresión regular simple, en realidad no puedo encontrar el objeto.

Gracias!

¿Fue útil?

Solución

Si estás interesado en hacer una comparación de patrones en los números, la forma de hacerlo en mongo es utilizar la expresión $ dónde y pasar de una coincidencia de patrón.

> db.test.find({ $where: "/^123.*/.test(this.example)" })
{ "_id" : ObjectId("4bfc3187fec861325f34b132"), "example" : 1234 }

Otros consejos

No soy un gran fan de utilizar el $where consulta operador debido a la forma en que se evalúa la expresión de consulta, no hace uso de índices y el riesgo de seguridad si la consulta utiliza los datos de entrada del usuario.

A partir de MongoDB 4.2 se puede utilizar el $regexMatch|$regexFind|$regexFindAll disponible en MongoDB 4.1.9+ y la $expr para hacer esto.

let regex = /123/;
  • $regexMatch y $regexFind

    db.col.find({
        "$expr": {
            "$regexMatch": {
               "input": {"$toString": "$name"}, 
               "regex": /123/ 
            }
        }
    })
    
  • $regexFinAll

    db.col.find({
        "$expr": {
            "$gt": [
                { 
                    "$size": { 
                        "$regexFindAll": { 
                            "input": {"$toString": "$name"}, 
                            "regex": "123" 
                        }
                    }
                }, 
                0
            ]
        }
    })
    

A partir de MongoDB 4.0 se puede utilizar el operador $toString que es una envoltura alrededor del operador $convert a stringify enteros.

db.seDemo.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$gt": [ 
                { "$indexOfCP": [ 
                    { "$toString": "$example" }, 
                    "123" 
                ] }, 
                -1 
            ] }, 
            "$$KEEP", 
            "$$PRUNE" 
        ] 
    }}
])

Si lo que quiere es recuperar todo el documento que contiene una subcadena en particular, a partir de la liberación 3.4, puede utilizar el $redact operador que permite a un $cond itional processing.$indexOfCP lógica.

db.seDemo.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$gt": [ 
                { "$indexOfCP": [ 
                    { "$toLower": "$example" }, 
                    "123" 
                ] }, 
                -1 
            ] }, 
            "$$KEEP", 
            "$$PRUNE" 
        ] 
    }}
])

que produce:

{ 
    "_id" : ObjectId("579c668c1c52188b56a235b7"), 
    "example" : 1234 
}

{ 
    "_id" : ObjectId("579c66971c52188b56a235b9"), 
    "example" : 12334 
}

Antes de MongoDB 3.4, es necesario $project su documento y añadir otro campo calculado que es el valor de la cadena de su número.

El $toLower y su hermano operadores $toUpper noreferrer nofollow convertir respectivamente una cadena a minúsculas y mayúsculas, pero tienen una característica poco desconocida que es que se pueden utilizar para convertir un entero en cadena.

$match operador devuelve todos aquellos documentos que responden a su búsqueda patrón usando el operador $regex .

db.seDemo.aggregate(
    [ 
        { "$project": { 
            "stringifyExample": { "$toLower": "$example" }, 
            "example": 1 
        }}, 
        { "$match": { "stringifyExample": /^123.*/ } }
    ]
)

que los rendimientos:

{ 
    "_id" : ObjectId("579c668c1c52188b56a235b7"), 
    "example" : 1234,
    "stringifyExample" : "1234"
}

{ 
    "_id" : ObjectId("579c66971c52188b56a235b9"), 
    "example" : 12334,
    "stringifyExample" : "12334"
}

Ahora, si lo que quiere es recuperar todo el documento que contiene una subcadena en particular, la manera más fácil y mejor de hacer esto es en el próximo lanzamiento de MongoDB (a partir de este escrito) utilizando el $redact operador que permite a un $cond itional processing.$indexOfCP lógica.

db.seDemo.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$gt": [ 
                { "$indexOfCP": [ 
                    { "$toLower": "$example" }, 
                    "123" 
                ] }, 
                -1 
            ] }, 
            "$$KEEP", 
            "$$PRUNE" 
        ] 
    }}
])
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top