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

Appel de la fonction db.system.js dans $where

Vous connectez-vous au même espace de noms de base de données dans votre code PHP que celui auquel vous vous êtes connecté à l'aide du shell ? Je ne pense pas !

Quoi qu'il en soit, vous comprenez mal le concept de $where dans ce contexte, puisque vous ne pouvez qu'évaluer et non revenir résultats modifiés autres que les données déjà contenues dans la collection.

Les seules choses qui peuvent réellement renvoyer quelque chose de différent des documents existants sont .mapReduce() et .aggregate() .

Donc pour démontrer, dans le "même espace de noms" si vous définissez une collection :

db.djunk.insert({ "x": 1, "y": 2 })

Et puis exécutez un .mapReduce()

db.dbjunk.mapReduce(
    function() {
        emit(this._id, sum(this.x,this.y))
    },
    function() {}, // does nothing here where already unique
    { "out": { "inline": 1 } }
)

Cela reviendrait un résultat total réel :

{
    "_id" : ObjectId("571a9bb951d042a7a896fd92"),
    "value" : 3
}

Tout ça $where peut faire, c'est "logiquement" sélectionner le document :

db.djunk.find(function() {
    return sum(this.x,this.y) > 3
})

Ce qui ne remplirait pas la condition.

Mais bien sûr, vous n'avez vraiment pas besoin de le faire et vous devriez généralement éviter toute exécution de JavaScript par le serveur dans la mesure du possible. C'est beaucoup plus lent que les opérateurs natifs, et vous pouvez faire beaucoup avec les opérateurs natifs.

Donc au lieu de .mapReduce() appeler .aggregate() :

db.djunk.aggregate([
    { "$project": {
        "total": { "$add": [ "$x", "$y" ] }
    }}
])

Et au lieu de l'évaluation JavaScript, appelez .aggregate() encore une fois, avec $redact pour le filtrage "logique" :

db.djunk.aggregate([
    { "$redact": {
        "$cond": {
            "if": { "$gt": [ { "$add": [ "$x", "$y" ] }, 3 ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }      
    }}
])

Ainsi, dans la plupart des cas, il existe toujours une meilleure alternative à l'utilisation de l'évaluation JavaScript. Et il y a certainement très peu de cas où les fonctions stockées sur le serveur sont réellement nécessaires dans les cas où une évaluation JavaScript est réellement requise.

Mais votre erreur de base ici sera parce que la fonction était dans un espace de noms différent, ou bien que vous avez redémarré le serveur entre les deux. Mais le point général est que vous ne devriez probablement pas utiliser les fonctions stockées de toute façon.