Como usar uma variável como um nome de campo em findOne () nativo de mongodb?

89

Eu tenho estes dados no mongodb:

{  
    "name": "Amey",
    "country": "India",
    "region": "Dhule,Maharashtra"
}

e eu quero recuperar os dados ao passar um nome de campo como uma variável na consulta.

O que se segue não funciona:

var name = req.params.name;
var value = req.params.value;
collection.findOne({name: value}, function(err, item) {
    res.send(item);
});

Como posso consultar o mongodb mantendo o nome do campo e seu valor dinâmicos?

WillMcavoy
fonte
Acabei de encontrar este post. Eu acho que isso é muito inseguro. Você não acha que deveria higienizar antes de usar esses valores em uma consulta?
McStuffins

Respostas:

142

Você precisa definir a chave do objeto de consulta dinamicamente:

var name = req.params.name;
var value = req.params.value;
var query = {};
query[name] = value;
collection.findOne(query, function (err, item) { ... });

When you do {name: value}, the key is the string 'name' and not the value of the variable name.

maxdec
fonte
What if you want to use operators such as $gt inside the query?
Savvas Parastatidis
You replace value by your query like { $gt: 50 }
maxdec
How to pass regular express using above solution var query = {}; query[name] = value; ?
Rohit Luthra
3
I succeed var query = {}; query['registrationNo'] = { "$regex": sCode, "$options": "m" } ;
Rohit Luthra
1
@levelone someone was faster than me :)
maxdec
60

Just put the variable in []

var name=req.params.name;
var value = req.params.value;
collection.findOne({[name]:value}, function(err, item) {
res.send(item);
});
KiwenLau
fonte
1
Your answer is much straight forward!
user523234
1
This doesn't work as a direct mongo query; you get an error back E QUERY SyntaxError: Unexpected token [. I'm not sure how it can work in node.js?
Vince Bowdren
I think the reason is that nodejs will do transformation when it interact with mongodb.
KiwenLau
this work on native mongodb drive for nodejs ! Thanks!
Guihgo
Thank you! This worked in my much more abstract code for which the accepted answer made no sense (for the record, react not nodeJs).
adinutzyc21
7

I'd like to clarify that if you're trying to make a query concerning a nested field only (not its value), like if you want to query the field "name" from this document:

{
    loc: [0, 3],
    unit: {
        name : "playername"
    }
}

this will work (as in my case - using update):

mdb.cords.updateOne(
    {_id: ObjectID(someid)}, 
    {$set: {[query]: newValue}}, 
    function (err, result) {
        ...
    }
}

Simply enclosing [query] in brackets tells mongodb that it's not literal, but rather a path.

hydrix
fonte
2

use like this if the object is nested.

Direct Object:-

var name=req.params.name;
var value = req.params.value;
collection.findOne({[name]:value}, function(err, item) {
res.send(item);
});

An object is nested:-

var surname=req.params.surname;
var value = req.params.value;
var condition = `name.${surname}`
collection.findOne({[condition]:value}, function(err, item) {
res.send(item);
});
Ankit Kumar Rajpoot
fonte
This helped, I was using 'name.${surname}' but for variable we don't use ', thanks
1UC1F3R616