MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Longueur de la valeur du champ de chaîne dans mongoDB

Pour MongoDB 3.6 et versions ultérieures :

Le $expr L'opérateur permet l'utilisation d'expressions d'agrégation dans le langage de requête, vous pouvez donc tirer parti de l'utilisation de $strLenCP pour vérifier la longueur de la chaîne comme suit :

db.usercollection.find({ 
    "name": { "$exists": true },
    "$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] } 
})

Pour MongoDB 3.4 et versions ultérieures :

Vous pouvez également utiliser le cadre d'agrégation avec le $redact opérateur de pipeline qui vous permet de traiter la condition logique avec le $cond opérateur et utilise les opérations spéciales $$KEEP pour "conserver" le document où la condition logique est vraie ou $$PRUNE pour "supprimer" le document où la condition était fausse.

Cette opération est similaire à un $project pipeline qui sélectionne les champs de la collection et crée un nouveau champ contenant le résultat de la requête de condition logique, puis un $match suivant , sauf que $redact utilise une seule étape de pipeline qui est plus efficace.

En ce qui concerne la condition logique, il existe des opérateurs d'agrégation de chaînes que vous pouvez utiliser $strLenCP opérateur pour vérifier la longueur de la chaîne. Si la longueur est $gt une valeur spécifiée, il s'agit d'une correspondance vraie et le document est "conservé". Sinon, il est "élagué" et jeté.

Envisagez d'exécuter l'opération d'agrégation suivante qui illustre le concept ci-dessus :

db.usercollection.aggregate([
    { "$match": { "name": { "$exists": true } } },
    {
        "$redact": {
            "$cond": [
                { "$gt": [ { "$strLenCP": "$name" }, 40] },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    },
    { "$limit": 2 }
])

Si vous utilisez $where , essayez votre requête sans les crochets :

db.usercollection.find({$where: "this.name.length > 40"}).limit(2);

Une meilleure requête serait de vérifier l'existence du champ, puis de vérifier la longueur :

db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2); 

ou :

db.usercollection.find({name: {$exists: true}, $where: "this.name.length > 
40"}).limit(2); 

MongoDB évalue non-$where opérations de requête avant $where expressions et non-$where les instructions de requête peuvent utiliser un index. Une bien meilleure performance consiste à stocker la longueur de la chaîne dans un autre champ, puis vous pouvez l'indexer ou la rechercher ; appliquer $where sera beaucoup plus lent par rapport à cela. Il est recommandé d'utiliser des expressions JavaScript et le $where opérateur en dernier recours lorsque vous ne pouvez pas structurer les données d'une autre manière ou lorsque vous traitez un petit sous-ensemble de données.

Une approche différente et plus rapide qui évite l'utilisation du $where l'opérateur est le $regex opérateur. Considérez le modèle suivant qui recherche

db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2); 

Remarque - À partir de la documentation :

Si un index existe pour le champ, MongoDB fait correspondre l'expression régulière aux valeurs de l'index, ce qui peut être plus rapide qu'une analyse de collection. Une optimisation supplémentaire peut se produire si l'expression régulière est une « expression de préfixe », ce qui signifie que toutes les correspondances potentielles commencent par la même chaîne. Cela permet à MongoDB de construire une "plage" à partir de ce préfixe et de ne faire correspondre que les valeurs de l'index qui se situent dans cette plage.

Une expression régulière est une "expression de préfixe" si elle commence par un accentuation (^) ou une ancre gauche (\A) , suivi d'une chaîne de symboles simples. Par exemple, la regex /^abc.*/ sera optimisé en comparant uniquement les valeurs de l'index qui commencent par abc .

De plus, tandis que /^a/, /^a.*/, et /^a.*$/ correspondent à des chaînes équivalentes, elles ont des caractéristiques de performance différentes. Toutes ces expressions utilisent un index si un index approprié existe; cependant,/^a.*/ , et /^a.*$/ sont plus lents. /^a/ peut arrêter l'analyse après la correspondance du préfixe.