MongoDB Regex Recherche sur Integer Valeur
-
04-10-2019 - |
Question
Je veux regex recherche une valeur entière dans MongoDB. Est-ce possible?
Je construis une interface de type CRUD qui permet * pour wildcards sur les différents domaines. J'essaie de garder l'interface utilisateur cohérente pour quelques champs qui sont des entiers.
Considérez:
> db.seDemo.insert({ "example" : 1234 });
> db.seDemo.find({ "example" : 1234 });
{ "_id" : ObjectId("4bfc2bfea2004adae015220a"), "example" : 1234 }
> db.seDemo.find({ "example" : /^123.*/ });
>
Comme vous pouvez le voir, j'insérer un objet et je suis capable de le trouver par la valeur. Si je tente un regex simple, je ne peux pas trouver en fait l'objet.
Merci!
La solution
Si vous êtes désireux de faire un match de modèle sur le nombre, la façon de le faire est en mongo utiliser le $ où l'expression et passer dans une correspondance de motif.
> db.test.find({ $where: "/^123.*/.test(this.example)" })
{ "_id" : ObjectId("4bfc3187fec861325f34b132"), "example" : 1234 }
Autres conseils
Je ne suis pas un grand fan d'utiliser le $where
requête opérateur en raison de la façon dont il évalue l'expression de requête, il ne pas utiliser les index et le risque de sécurité si la requête utilise des données d'entrée de l'utilisateur.
A partir de MongoDB 4.2, vous pouvez utiliser le $regexMatch|$regexFind|$regexFindAll
disponible dans MongoDB 4.1.9+ et $expr
de le faire.
let regex = /123/;
-
$regexMatch
et$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 ] } })
De MongoDB 4.0, vous pouvez utiliser l'opérateur $toString
qui est un wrapper autour de l'opérateur de $convert
stringify entiers.
db.seDemo.aggregate([
{ "$redact": {
"$cond": [
{ "$gt": [
{ "$indexOfCP": [
{ "$toString": "$example" },
"123"
] },
-1
] },
"$$KEEP",
"$$PRUNE"
]
}}
])
Si ce que vous voulez est de récupérer tout le document qui contient une sous-chaîne particulier, à partir de version 3.4, vous pouvez utiliser le $redact
opérateur qui permet une $project
votre document et ajouter un autre champ calculé qui est la valeur de chaîne de votre numéro.
Le $toLower
et son frère $match
renvoie l'opérateur tous les documents qui correspondent à votre motif en utilisant l'opérateur $regex
.
db.seDemo.aggregate(
[
{ "$project": {
"stringifyExample": { "$toLower": "$example" },
"example": 1
}},
{ "$match": { "stringifyExample": /^123.*/ } }
]
)
qui donne:
{
"_id" : ObjectId("579c668c1c52188b56a235b7"),
"example" : 1234,
"stringifyExample" : "1234"
}
{
"_id" : ObjectId("579c66971c52188b56a235b9"),
"example" : 12334,
"stringifyExample" : "12334"
}
Maintenant, si ce que vous voulez est de récupérer tout le document qui contient une sous-chaîne particulière, plus facile et une meilleure façon de le faire est dans la prochaine version de MongoDB (de cette écriture) en utilisant le $redact
opérateur qui permet une $cond
itional processing.$indexOfCP
logique.
db.seDemo.aggregate([
{ "$redact": {
"$cond": [
{ "$gt": [
{ "$indexOfCP": [
{ "$toLower": "$example" },
"123"
] },
-1
] },
"$$KEEP",
"$$PRUNE"
]
}}
])