I want to update a property in whole database.
Example I want to update property name if name=='Gaurav' then I want to replace this as name='gsb' in all documents in all collections, whether it is nested objects property. Is there any way to do this without knowing the structure of document, cause in each collection documents are of different structure. I want this query for Node JS.
What I tried is as follows. I am stuck in between.
var MongoClient = require('mongodb').MongoClient;
var config = require('../config.js');
var async = require('async');
_ = require ('lodash');
MongoClient.connect('mongodb://' + config.db_url + '/' + config.db_name, function(err, db) {
if(err) throw err;
db.listCollections().toArray(function(err, collInfos) {
async.each(collInfos,function(collectionDetails,cb){
db.collection(collectionDetails.name,function(err, collection){
if(err){
console.log(err)
}
else
{
collection.find().toArray(function(error, result) {
if(error) {
console.log(error);
}
else {
_depthFirstSearch = (collection, input) => {
let type = typeof collection;
if (type === 'string' || type === 'number' || type === 'boolean') {
return _.includes(collection.toString().toLowerCase(), input.toString().toLowerCase());
}
return _.some(collection, (item) => this._depthFirstSearch(item, input));
}
var data= _.filter(result, (item) => {
return _depthFirstSearch(item, "Gaurav");
});
console.log(data)
}
});
}
})
cb();
})
});
});
I found the solution after lots of brainstorm. I wrote below function to achieve this.
var replaceAllInsatnceInDB=function(db_url/*localhost:27017*/,db_name,propName,stringToSearch,stringToReplace){
MongoClient.connect('mongodb://' + db_url + '/' + db_name, function(err, db) {
if(err) throw err;
db.listCollections().toArray(function(err, collInfos) {
async.each(collInfos,function(collectionDetails,cb){
db.collection(collectionDetails.name,function(err, collection){
if(err){
console.log(err)
}
else
{
collection.find().toArray(function(error, result) {
if(error) {
console.log(error);
}
else {
result.forEach(function(document){
var op=function(record){
if(record!== null && record!==undefined ){
var props=Object.keys(record);
var forObject=function(obj){
if(Array.isArray(obj)){
var forArray=function(arr){
for(var j=0;j<arr.length;j++){
if(typeof arr[j] ==="string"){
if(arr[j]===stringToSearch && props[i]==propName){
arr[j]=stringToReplace
}
}
if(typeof arr[j] ==="object"){
forObject(arr[j]);
}
}
return(arr)
}
obj=forArray(obj)
}else{
op(obj);
}
return(obj);
}
for(var i=0;i<props.length;i++){
if(typeof record[props[i]] ==="string"){
if(record[props[i]]===stringToSearch && props[i]==propName){
record[props[i]]=stringToReplace
console.log()
}
}
if(typeof record[props[i]] ==="object"){
record[props[i]]=forObject(record[props[i]])
}
}
}
return(record);
}
document=op(document);
collection.update({_id : document._id},document,function(error,doc){
if(error){
console.log(error)
}else{
console.log("template updated");
}
})
})
}
});
}
})
cb();
})
});
});
}
Related
After some agonizing weeks of trying to find the core of my problem, I found it. What I want to know is what's the reason for this behaviour.
I built an api for my mongodb server the way I learned in school using Model,Controller,Routes.
In my lobbyRoutes.js it turns out that if I write
router.get('/:lobbyID',controller.get);
Another function:
router.get('/getAvailable',controller.getAvailable)
- will return null when I type in the URL (.../api/lobbies/getAvailable - just returns the word null instead of a json).
Meanwhile if I make this little change:
router.get('/get/:lobbyID',controller.get); (add a 'get/' before ':lobbyID') will fix the problem and getAvailable returns a json as expected and not a null anymore.
lobbyRoutes.js:
var controller = require('./LobbyController');
router.post('/insert',controller.insert);
router.get('/getall',controller.getall);
router.get('/get/:lobbyID',controller.get); //the one that affects
router.post('/update',controller.update);
router.post('/delete',controller.delete);
router.get('/getAvailable',controller.getAvailable); // the one that is affected
router.post('/connect',controller.connect);
router.post('/disconnect',controller.disconnect);
router.get('/getable',controller.getable);
module.exports = router;
and if it helps, lobbyController.js :
exports.get = function(req, res,next){
CurrentLobby.findOne({_id:req.params.lobbyID}).then(function(data){
res.json(data);
},function(err){
next(err);
});
};
exports.getall = function(req, res, next){
CurrentLobby.find( {} ).then(function(data){
res.json(data)
},
function(err){
next(err);
}
);
};
exports.getable = function(req,res,next){
CurrentLobby.findOne({isAvailable:true}).then(function(data){
res.json(data)
},
function(err)
{
next(err);
});
};
exports.insert = function(req, res, next){
var isAvailable = true;
var playerCount = 0;
var playerArray = [];
var PINCODE = -1;
var gameMode = "";
var currentWord = "";
var query = {title:"Index"};
CurrentLobby.findOne({_id:"5d7a9060004a5c3318d0db98"
}).then(function(data){
console.log(data);
var lobby = {title:"Lobby_"+(data.playerCount+1).toString(), isAvailable:isAvailable,playerCount:playerCount,playerArray:playerArray,PINCODE:PINCODE,gameMode:gameMode,currentWord:currentWord};
var newItem = new CurrentLobby(lobby);
newItem.save(function(err, item){
if(err){
next(err);
}
res.json(item);
});//end of save
CurrentLobby.findOne(query).then(function(data){
data.playerCount++;
data.save(function(err,item)
{
if(err) {next(err)};
console.log("index incremented");
});
},
function(err)
{
next(err);
});
},function(err)
{
next(err);
});
};
exports.delete = function(req, res, next){
CurrentPost.remove({_id:req.body._id}).then(function(){
res.send("deleted " + req.body._id);
}, function(err){
next(err);
}
);
} ;
exports.update = function(req, res, next){
CurrentLobby.findOne({_id:req.query.lobbyID}).then(function(data){
data.isAvailable = (typeof req.body.isAvailable == 'undefined') ? data.isAvailable : req.body.isAvailable;
data.playerCount = (typeof req.body.playerCount=='undefined') ? data.playerCount : req.body.playerCount;
data.playerArray = (typeof req.body.playerArray=='undefined') ? data.playerArray : req.body.playerArray;
data.PINCODE = (typeof req.body.PINCODE=='undefined') ? data.PINCODE : req.body.PINCODE;
data.gameMode = (typeof req.body.gameMode=='undefined') ? data.gameMode : req.body.gameMode;
data.currentWord = (typeof req.body.currentWord=='undefined') ? data.currentWord : req.body.currentWord;
data.save(function(err, item){
if(err){
next(err);
}
res.json(item);
});
},function(err){
next(err);
});
};
exports.getAvailable=function(req,res,next)
{
var query = {isAvailable:true};
CurrentLobby.findOne(query).then(function(data){
res.json(data);
},
function(err){
next(err);
}
);
};
exports.connect=function(req,res,next)
{
var query={_id:req.query.lobbyID}
CurrentLobby.findOne(query).then(function(data)
{
console.log("called connect, user:"+req.query.userID+", lobby:"+req.query.lobbyID);
data.isAvailable=false;
if (typeof data.playerArr !== 'undefined' && data.playerArr.length >= 0) {
// the array is defined and has at least one element
data.playerArr.push(req.query.userID);
console.log("successfully added user");
data.playerCount++;
if(data.playerCount==8)
data.isAvailable=false;
}
else{
data.playerArr.push(req.query.userID);
console.log("1st user");
}
data.save(function(err, item){
if(err){
next(err);
}
res.json(item);
});
},
function(err)
{
next(err);
});
};
exports.disconnect=function(req,res,next)
{
var query={_id:req.query.lobbyID}
CurrentLobby.findOne(query).then(function(data)
{
console.log("called disconnect, user:"+req.query.userID+", lobby:"+req.query.lobbyID);
data.isAvailable=false;
if (typeof data.playerArr !== 'undefined' && data.playerArr.length >= 0) {
// the array is defined and has at least one element
var index = data.playerArr.indexOf(req.query.userID);
if (index !== -1){ data.playerArr.splice(index, 1);
console.log("successfully removed user");
data.playerCount--;
//room available
if(data.playerCount==0)
{
data.PINCODE=-1;
data.gameMode="";
data.currentWord="";
data.isAvailable=true;
}
}
else{
console.log("not found");
}
}
else console.log("array is empty");
data.save(function(err, item){
if(err){
next(err);
}
res.json(item);
});
},
function(err)
{
next(err);
});
};
I just would like to know why I can't type a parameter first (even though it doesn't affect the function itself, only the other one). Thanks.
As user 'Mike Pomax Kamermans' said, using parameter first in order will break all of the other routes so the word getAvailable will be recognized as a lobbyID paramater rather than call the function 'getAvailable'. quite embarassed I could not figure it out alone...
I have this problem, although I managed the value of "result", the conditional expression "if" evaluates "result" always as "! == undefined" I also tried to manage with "result! == ''" but not handles it correctly. In this case I have no results from the sql query because "ricovero.cps" is not in the database and so I wrote some code to handle this case. How should I behave in order for the "if" to work correctly?
function getIdCPS(ricovero){
console.log("getIdCPS()");
querySQL = "SELECT id FROM codici_pronto_soccorso WHERE codice ='"+ricovero.cps+"'";
console.log("querySQL="+querySQL);
try{
connection.query(querySQL, function(err, result) {
if(err)
console.log(err);
if( result === undefined){
return "";
}else{
console.log("result is defined");
console.log("result=("+result+")");
return result[0].id;
}
});
}catch(e){
console.log("try/catch error:" + e);
}
}
Just put this code and monitor on console
const getIdCPS = (ricovero) => {
try {
const errorObj = { code: 400, error: 'Wrong Input' }
if (!ricovero || !ricovero.cps) {
throw errorObj;
}
const querySQL = "SELECT id FROM codici_pronto_soccorso WHERE codice ='" + ricovero.cps + "'";
connection.query(querySQL, (err, result) => {
if (err) {
throw err;
} else if (result) {
console.log(result);
return result;
} else {
throw err;
}
});
} catch (err) {
console.error(err);
throw err;
}
};
So i have implemented a mongodb on my nodejs server. And what I have done is store users via:
function insertUser() {
var collection = dbb.collection('user');
var user1 = {name: user, token: token};
collection.insert(user1, function(err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
}
function findUserByName(devName) {
var collection = dbb.collection('user');
collection.find({name: devName}).toArray(function (err, result) {
if (err) {
console.log(err);
} else if (result.length) {
console.log('Found: ', result);
selectedUserToken = result.token;
} else {
console.log('No document found');
insertUser();
}
dbb.close();
});
}
So result will equal:
Found: [ { _id: 57be1cadc281c03ea116c9ab,
name: 'Austin Hunter',
token: 'dJyXVjMJk08kXWrua8SUjKb....SxACihKZoR53y_wOZmcFNKMmD5q99QNvsp3flL' } ]
My question is, how can I get that token out to equal selectedUserToken so I can send a push notification with gcm? Right now result.token is undefined.
You should use findOne() instead of find() since you only expect a single result back:
function findUserByName(devName) {
var collection = dbb.collection('user');
collection.findOne({name: devName}, function (err, result) {
if (err) {
console.log(err);
} else if (result) {
console.log('Found: ', result);
selectedUserToken = result.token;
} else {
console.log('No document found');
insertUser();
}
dbb.close();
});
}
But if you wanted to leave your code as is with the find() you would just retrieve the first element of the resulting array retrieved by find()
function findUserByName(devName) {
var collection = dbb.collection('user');
collection.find({name: devName}).toArray(function (err, result) {
if (err) {
console.log(err);
} else if (result.length) {
console.log('Found: ', result);
selectedUserToken = result[0].token;
} else {
console.log('No document found');
insertUser();
}
dbb.close();
});
}
Maybe result[0].token, because result is an array of user items.
I am working in sails js. And i want to return the variable sequence[0].NextValue;. But I am not getting it.
function AutoGenerate(tablename)
{
Sequence.find({TableName:tablename}).exec(function(err,sequence){
if(err)
{
console.log("err");
return res.negotiate(err);
}
else
{
console.log(sequence);
var intCurrentNo = sequence[0].NextValue;
var intNextNo = sequence[0].NextValue + sequence[0].IncrementBy;
if (intNextNo < sequence[0].MinimumValue || intNextNo > sequence[0].MaximumValue)
{
console.log("Error While Updating UserId")
return res.badRequest('Next value not between the Minimum and Maximum value');
}
else
{
sequence[0].NextValue = intNextNo;
console.log(intNextNo);
sequence[0].save(function(err)
{
if (err)
{
console.log("error while update");
return res.negotiate(err);
}
else
{
console.log("Incremented");
console.log(sequence[0].NextValue);
return sequence[0].NextValue;
}
});
}
}
});
}
But the Sequence.find({TableName:tablename}) function does not returning any value. Please help me to get rid of this.
You can't return a value cause it's an asynchronous method you have to do it with callbacks :
function AutoGenerate(tablename, callback)
{
Sequence.find({TableName : tablename}).exec(function (err, sequence)
{
if (err)
{
console.log("err");
callback(err);
}
else
{
console.log(sequence);
var intCurrentNo = sequence[0].NextValue;
var intNextNo = sequence[0].NextValue + sequence[0].IncrementBy;
if (intNextNo < sequence[0].MinimumValue || intNextNo > sequence[0].MaximumValue)
{
console.log("Error While Updating UserId")
callback(new Error('Next value not between the Minimum and Maximum value'));
}
else
{
sequence[0].NextValue = intNextNo;
console.log(intNextNo);
sequence[0].save(function (err)
{
if (err)
{
console.log("error while update");
callback(err);
}
else
{
console.log("Incremented");
console.log(sequence[0].NextValue);
callback(null, sequence[0].NextValue);
}
});
}
}
});
}
And call it like this :
AutoGenerate("myTableName", function(err, nextValue){
if(err){res.negotiate(err);}
else {/* DO WHAT YOU WANT */}
});
I need some advice on how to re/write the db specific cascading code (callback) so that I can effectively return a value to the underlying if/else.
I am using restify and the db lib is node-mssql (tedious).
function authenticate(req, res, next) {
var auth = req.authorization;
var err;
if (auth.scheme !== 'Basic' || ! auth.basic.username || ! auth.basic.password) {
authFail(res);
err = false;
} else {
var sql = "SELECT ..."
var connection = new mssql.Connection(config.mssql, function(err) {
if (err) {console.log(err);}
var request = connection.request();
request.query(sql, function(err, recordset) {
if (err) {console.log(err);}
if (recordset.length === 0) {
authFail(res);
err = false; // <--- I need to be able to return this
} else {
authSuccess();
}
});
});
}
next(err);
}
I've reviewed the suggested duplicate, and while I think, I understand the issue, I can't work out the cleanest (lets be honest any) way to get this to work.
How about using Promises?
function authenticate(req, res, next) {
var auth = req.authorization;
if (auth.scheme !== 'Basic' || ! auth.basic.username || ! auth.basic.password) {
authFail(res);
next(false);
} else {
var sql = "SELECT ..."
var connection = new mssql.Connection(config.mssql, function(err) {
if (err) {console.log(err);}
var request = connection.request();
request.query(sql).then(function(recordset) {
if (recordset.length === 0) {
authFail(res);
return false; // <--- return this
} else {
authSuccess();
}
}).catch(function(err) {
console.log(err);
return err;
}).then(function(err) { next(err); });
});
}
}