如何在MongoDB中使用外部变量'where'通过Javascript查询?

时间:2015-12-22 21:03:03

标签: javascript mongodb mongodb-query

我有一个MongoDB查询,它在所有属性中搜索搜索变量中定义的值。它的工作方式如下:

standalone.sh -b 0.0.0.0 -bmanagement=0.0.0.0

但是,我想在查询之外定义搜索变量。

但是当我这样做时,我得到一个错误,它没有被引用(即范围问题):

 db.collection.findOne({
                $where: function() {
                    var search = 'searchstring';
                    for (var key in this) {
                        if (this[key] === search) {
                          return true;
                        }
                        return false;
                    }
                }
            });

如何使用或将变量传递给查询过滤器?

3 个答案:

答案 0 :(得分:9)

You can try something like this:

var searchstring = 'whatever';
var params = {};
params.$where = 'function() {' +
    'var search = "' + searchstring + '";' +
    'for (var key in this) {' +
        'if (this[key] === search) {' +
            'return true;' +
        '}' +
        'return false;' +
    '}' +
'}';
db.collection.findOne(params);

(Stringify your function and concat with external variable)

Worked for me via mongoose

答案 1 :(得分:1)

您可以使用mongodb map reduce和scope功能解决此问题。 Scope允许您将变量传递给map reduce job。

function map() {
    for (var key in this) {
        if (this[key] === search) {
            return emit(this._id, this);
        }
    }
}

function reduce(key, values) {
    return values[0];
}


db.collection.mapReduce(map, reduce, {
        out: {inline: 1},
        scope: {
            search: 'searchstring'
        }
    }
);

答案 2 :(得分:0)

search是您在客户端中定义的变量,可能是shell或任何客户端API。

您为$where子句定义的函数不会在客户端执行,而是在mongodb服务器上执行。 因此,当在服务器端解释函数并且它查找search变量时,它从未在服务器上定义,因此您会收到错误。

在您的情况下,您希望变量search在服务器上执行之前由客户端替换为其内容。除非您在客户端构建功能内容,否则这是不可能的。

客户端永远不会真正解释您在匿名函数中编写的任何内容。 服务器。您看到的错误来自服务器。您可以通过触发此查询并查看服务器日志来验证它:

2015-12-22T19:03:44.011-0800 I QUERY    [conn1] assertion 16722 ReferenceError:
searc is not defined
    at _funcs1 (_funcs1:1:39) near 's.key === searc){retu'  ns:test.t query:{ $w
here: function (){if(this.key === searc){return true}} }

使用$exists运算符可以更好地编写您希望实现的内容。

var search = "title";
var find = {};
find[search] = {$exists:true};
db.collection.findOne(find);

这是有效的,因为您在将查询参数传递给findOne()方法之前,在客户端完全构建查询参数。