MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Chamando a função db.system.js em $where


Você está se conectando ao mesmo namespace de banco de dados em seu código PHP ao qual você se conectou usando o shell? Eu acho que não!

De qualquer forma, você não entendeu o conceito de $where nesse contexto, pois você só pode avaliar e não retornar resultados modificados além dos dados já contidos na coleção.

As únicas coisas que podem realmente retornar algo diferente dos documentos existentes são .mapReduce() e .aggregate() .

Então, para demonstrar, no "mesmo namespace" se você definir uma coleção:
db.djunk.insert({ "x": 1, "y": 2 })

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

Isso retornaria um resultado real somado:
{
    "_id" : ObjectId("571a9bb951d042a7a896fd92"),
    "value" : 3
}

Tudo isso $where pode fazer, é "logicamente" selecionar o documento:
db.djunk.find(function() {
    return sum(this.x,this.y) > 3
})

O que não atenderia à condição.

Mas é claro que você realmente não precisa fazer isso, e geralmente deve evitar qualquer execução de servidor JavaScript sempre que possível. É muito mais lento que os operadores nativos e você pode fazer bastante com os operadores nativos.

Então, em vez de .mapReduce() chame .aggregate() :
db.djunk.aggregate([
    { "$project": {
        "total": { "$add": [ "$x", "$y" ] }
    }}
])

E em vez de avaliação JavaScript, chame .aggregate() novamente, com $redact para filtragem "lógica":
db.djunk.aggregate([
    { "$redact": {
        "$cond": {
            "if": { "$gt": [ { "$add": [ "$x", "$y" ] }, 3 ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }      
    }}
])

Portanto, na maioria dos casos, sempre há uma alternativa melhor do que usar a avaliação JavaScript. E certamente há muito poucos casos para realmente precisar de funções armazenadas no servidor nos casos em que a avaliação do JavaScript é realmente necessária.

Mas seu erro básico aqui será porque a função estava em um namespace diferente ou, na verdade, você reiniciou o servidor no meio. Mas o ponto geral é que você provavelmente não deveria usar funções armazenadas de qualquer maneira.