MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Aufruf der Funktion db.system.js in $where

Verbinden Sie sich in Ihrem PHP-Code mit demselben Datenbank-Namespace, mit dem Sie sich über die Shell verbunden haben? Ich denke nicht!

Wie auch immer, Sie missverstehen das Konzept von $where in diesem Zusammenhang, da Sie nur bewerten können und nicht zurück andere geänderte Ergebnisse als die bereits in der Sammlung enthaltenen Daten.

Die einzigen Dinge, die tatsächlich etwas anderes als die vorhandenen Dokumente zurückgeben können, sind .mapReduce() und .aggregate() .

Um das zu demonstrieren, im "gleichen Namensraum", wenn Sie eine Sammlung definieren:

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

Führen Sie dann ein .mapReduce() aus

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

Das würde zurückkehren ein tatsächliches summiertes Ergebnis:

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

All das $where tun kann, ist "logisch" das Dokument auszuwählen:

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

Was die Bedingung nicht erfüllen würde.

Aber natürlich müssen Sie dies nicht wirklich tun und sollten generell jede Serverausführung von JavaScript nach Möglichkeit vermeiden. Es ist viel langsamer als native Operatoren und Sie können mit nativen Operatoren einiges erreichen.

Also statt .mapReduce() Rufen Sie .aggregate() auf :

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

Rufen Sie statt der JavaScript-Auswertung .aggregate() auf wieder mit $redact für "logische" Filterung:

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

Daher gibt es in den meisten Fällen immer eine bessere Alternative zur JavaScript-Auswertung. Und sicherlich gibt es tatsächlich sehr wenige Fälle, in denen tatsächlich servergespeicherte Funktionen benötigt werden, wenn JavaScript-Evaluierung tatsächlich erforderlich ist.

Aber Ihr grundlegender Fehler hier wird sein, dass sich die Funktion in einem anderen Namensraum befand oder dass Sie den Server zwischendurch neu gestartet haben. Aber der allgemeine Punkt ist, dass Sie wahrscheinlich sowieso keine gespeicherten Funktionen verwenden sollten.