Mongodb $onde a pesquisa é sempre verdadeira com os nodejs

Quando questiono a minha base de dados com uma função passada na cláusula "$where" em nodejs, ela devolve-me sempre todos os documentos no db.

por exemplo, se eu fizer

var stream = timetables.find({$where: function() { return false; }}).stream();
Devolve-me todos os documentos. Em vez disso, se eu fizer

var stream = timetables.find({$where: 'function() { return false; }'}).stream();

a função é realmente executada, e este código não devolve nenhum documento.

o problema é que se eu converter em cadeia a minha função os bindindindindinds do contexto são removidos, e eu preciso deles para uma consulta mais complexa. Para exemplo:

var n = 1;
var f = function() { return this.number == n; }
var stream = timetables.find({$where: f.toString()}).stream();
// error: n is not defined
Isto é um comportamento normal? Como posso resolver o meu problema? Por favor, desculpem-me pelo meu pobre Inglês!

Author: Duma, 2013-03-25

7 answers

Em primeiro lugar, tenha em mente que o operador $where quase nunca deve ser usado pelas razões explicadas aqui (o crédito vai para @WiredPrairie).

[[6]] voltando ao seu problema, a abordagem que você gostaria de tomar não vai funcionar mesmo na concha mongodb (que explicitamente permite funções js nu com o operador $where). O código javascript fornecido ao operador $where é executado no servidor mongo e não terá acesso ao ambiente envolvente (o "contexto" ligacoes").
> db.test.insert({a: 42})
> db.test.find({a: 42})
{ "_id" : ObjectId("5150433c73f604984a7dff91"), "a" : 42 }
> db.test.find({$where: function() { return this.a == 42 }}) // works
{ "_id" : ObjectId("5150433c73f604984a7dff91"), "a" : 42 }
> var local_var = 42
> db.test.find({$where: function() { return this.a == local_var }})
error: {
    "$err" : "error on invocation of $where function:\nJS Error: ReferenceError: local_var is not defined nofile_b:1",
    "code" : 10071
}
Além disso, parece ser o nó.o driver nativo do js mongo comporta-se de forma diferente da shell, na medida em que não serializa automaticamente uma função js que você fornece no objeto de consulta e, em vez disso, provavelmente retira a cláusula completamente. Isto deixá-lo-á com o equivalente a timetables.find({}) que devolverá todos os documentos da colecção.
 4
Author: Utaal, 2013-03-25 12:40:24

Este funciona para mim, basta tentar armazenar uma consulta como uma string em uma variável, em seguida, concate a sua variável em query string,

Var local_var = 42

Var query = " {$where: function () {return this.a = " +local_var+"}}"

Db.teste.find (query)

 2
Author: Ashish Maradiya, 2017-08-30 11:20:09

Guarde a sua consulta numa varibale e use essa variável na sua pesquisa de procura. Funciona..... : D

 2
Author: Mitesh Rathod, 2017-08-30 11:32:10

O contexto será sempre o da base de dados mongo, uma vez que a função é executada lá. Não há como compartilhar o contexto entre as duas instâncias. Você tem que repensar a maneira como você consulta e chegar a uma estratégia diferente.

 1
Author: ExxKA, 2013-03-25 10:46:17

Pode usar uma embalagem para passar os objectos JSON básicos, ou seja. (pardon coffee-script):

# That's the main wrapper.
wrap = (f, args...) ->
  "function() { return (#{f}).apply(this, #{JSON.stringify(args)}) }"

# Example 1
where1 = (flag) ->
  @myattr == 'foo' or flag

# Example 2 with different arguments
where2 = (foo, options = {}) ->
  if foo == options.bar or @_id % 2 == 0
    true
  else
    false

db.collection('coll1').count $where: wrap(where1, true), (err, count) ->
  console.log err, count

db.collection('coll1').count $where: wrap(where2, true, bar: true), (err, count) ->
  console.log err, count

As tuas funções vão passar por algo como:

function () {
    return (function (flag) {
        return this.myattr === 'foo' || flag;
    }).apply(this, [true])
}

...e Exemplo 2:

function () {
    return (
        function (foo, options) {
            if (options == null) {
                options = {};
            }
            if (foo === options.bar || this._id % 2 === 0) {
                return true;
            } else {
                return false;
            }
        }
    ).apply(this, [ true, { "bar": true } ])
}
 1
Author: Mirek Rusin, 2014-04-04 13:19:30
É assim que deve ser. Os drivers não traduzem o código cliente para o código javascript da função mongo.
 0
Author: Munim, 2013-03-25 11:07:46

Presumo que esteja a usar Mangusto para consultar a sua base de dados.

Se der uma vista de olhos na implementação do objecto de pesquisa actual, irá descobrir que apenas as cadeias são argumentos válidos para o onde o protótipo .

Ao usar a cláusula onde, você deve usá-la juntamente com os operadores padrão, como gt, lt, que opera no caminho criado pela função onde.

Lembre-se que o mangusto questionando, como em Mongo, é por exemplo, você pode quer reconsiderar a sua especificação de consulta de uma forma mais descritiva.

 0
Author: Daniele Gallingani, 2013-03-25 11:19:48