Mongoose update array of Object id's using Populate? - mongodb

I am trying to populate my array of an object id's how can i do ??
Function
$scope.assignEmployees = function () {
var chkArray = [];
var companyName = $scope.selectedComapny.companyName;
var Indata = {chkvalue:chkArray,company_name:companyName};
$("#employee_name:checked").each(function() {
chkArray.push($(this).val());
});
$http({
method : 'PUT',
url : '/api/projects',
data : Indata
})
.success(function (data){
console.log(data);
});}
Mongoose api
Population code:-
Project.findOne({client : company_name})
.populate('assignedTo')
.exec(function(err, project) {
if (err) return;
while(i<employee_id.length){
project.assignedTo.push(employee_id[i]);
project.save(function(err) {
if (err) return;
})
i++;
}
});
This code is work but it insert value 4 times any idea guys.

You can use this code to push all elements of Array to an Array in mongoose.
Project.update(
{ client: company_name },
{ "$pushAll": { "assignedTo": employee_id } },
function (err, raw) {
if (err) return handleError(err);
console.log('The raw response from Mongo was ', raw);
}
);

Related

Get data according _id

I try to query MongoDB inside nodejs to get data for _id x I use
async function getTestData(id){
return new Promise((resolve, reject) => {
MongoClient.connect(uri, { useNewUrlParser: true, keepAlive: 1 }, function(err, client) {
const dbo = client.db("test");
var query = { _id: id };
dbo
.collection("smscripts")
.find(query)
.project({ 'data' : 1})
.toArray(function(err, items) {
err
? reject(err)
: resolve(items);
});
});
});
}
Query is
{ _id: '5dada7dfdca94dbaf65d9547' }
But I always get back an empty array. Anybody can help me out why the array is always empty? By the way, err is null. The id definitely exists.
in mongo db _id are prefix with ObjectId
so you need value first try this
id = ObjectId("507c7f79bcf86cd7994f6c0e")
and then compare it to ID.
hope it helps
First You need to import..
import { ObjectId } from "bson"
Then in Your code " var query = { _id: id }; " replace it with this..
var query = { '_id' : ObjectId(id) }
Then, in your code you are using .toArray() method. this would takes more time to
convert result to array. so you need to use await keyword before moving on.
Using Async-Await pattern this is very simple ..
const client = await MongoClient.connect(uri, { useNewUrlParser: true, keepAlive: 1 })
.catch(err => { console.log(err); });
if (!client) return;
try {
const dbo = client.db('test');
let collection = dbo.collection('smscripts');
let query = { '_id' : ObjectId(id) };
let projection = { 'data' : 1 } ;
let cursor = await collection.find(query, projection).toArray();
console.log(cursor);
return cursor;
} catch (err) {
console.log(err);
} finally {
client.close();
}
hope this works for you.

Bulk deleting documents from aggregate

I am trying to use a bulk delete on the results of a mongoose aggregate query.
var bulk = Collection.collection.initializeUnorderedBulkOp();
var cursor = Collection.aggregate(query).cursor({batchSize: 1000}).exec();
cursor.each(function(error, doc){
if(doc){
console.log(doc);
bulk.find({_id : doc._id}).removeOne();
}
});
if(bulk.length > 0) {
bulk.execute(function(error){
if(error){
console.error(error);
callback(error);
}else{
console.log(bulk.length + " documents deleted");
callback(null);
}
});
} else {
console.log("no documents to delete");
callback(null);
}
This results in the "no documents to delete" being printed before the results of the aggregate in the each loop. Normally I would expect there to be a callback function for a database operation. I have tried adding a callback function to the params of exec, but the function never gets hit:
var cursor = Collection.aggregate(query).cursor({batchSize: 1000}).exec(function(error, result){
console.log(error);
console.log(result);
callback();
});
Listen to the data and end events on the cursor:
cursor.on( 'data', function( data ) {
bulk.find( { "_id" : data._id } ).removeOne();
});
cursor.on( 'end', function() {
if ( bulk.length === 0 ) {
callback();
} else {
bulk.execute(function (error) {
if (error) {
callback(error);
} else {
callback();
}
});
}
});
What version of Mongoose? There's an issue on github that might be relevant. So maybe try:
var stream = Model
.aggregate(pipeline)
.cursor({ batchSize: 1000 })
.exec().stream();
stream.on('data', function(doc) {
// ...
});

mongoose can't save data

I meet some trouble need your help ~~ thx
I am use mongoose + superAgent + feedparser + eventProxy to get Rss and save these datas
now I can get and finish parse these dataes however I can't save them with moogose
I have 3 module are dao.js , app.js and service.js
I configure dao as this codes
var mongoose = require("mongoose"),
db,
modelName = "news"; // 设定操作的collections
mongoose.connect("mongodb://localhost:27017/test");
db = mongoose.connection;
db
.on("error", function (err) {
console.log("Connection Error!!! this's some prompts: ");
console.log(err);
})
.once("open", function () {
console.log("Open DataBase Successfully!!!");
});
// 设置
var newsSchema = mongoose.Schema({
"category": String,
"data": [{
"title": String,
"link": String,
"pubDate": String,
"source": String,
"author": String
}]
});
console.log(newsSchema.ObjectId);
newsSchema.pre("save", function (next) {
if( !this.title ) {
this.title = "未知标题";
}
next();
})
var newsModel = mongoose.model(modelName, newsSchema);
module.exports = {
model: newsModel,
schema: newsSchema,
mongoose,
db
}
and save data as these codes:
saveData(callback) {
var $self = this;
for(var i = 0; i<$self.result.length; i++) {
new model($self.result[i]).save(function (err) {
if(err) {
console.log(err)
} else {
console.log("数据存储成功!")
}
});
}
callback && callback();
db.close();
}
Now the data can't save successfully meanwhile the save callback func don't run
Could you give me some advise?

MEAN: Getting total value from mongodb

Im new to mean stack and Im using mongoskin to connect to mongodb..Im trying to get total value present in database
function getTotal() {
var deferred = Q.defer();
var dashboard = db.collection('dashboard');
db.collection('dashboard').find({"iscorrect" : ""}).count(),
function (err, doc) {
if (err){
deferred.reject(err);
} else{
deferred.resolve();
}
};
return deferred.promise;
}
my main controller has
function gettotal(req, res) {
userService.getTotal()
.then(function () {
res.sendStatus(200);
})
.catch(function (err) {
res.status(400).send(err);
});
}
The following code does not return any value...Any help in getting total value is helpful
Because count() method is asynchronous and returns a promise, you can restructure your function as either using a callback function
function getTotal() {
var deferred = Q.defer();
db.collection('dashboard').count({"iscorrect" : ""}, function (err, result) {
if (err){
deferred.reject(err);
} else{
deferred.resolve(result);
}
});
return deferred.promise;
}
or since count() returns a Promise, just return it
function getTotal() {
// just return a Promise
return db.collection('dashboard').count({"iscorrect" : ""});
}
and in your controller:
function gettotal(req, res) {
userService.getTotal()
.then(function (count) {
res.status(200).json({ 'count': count });
})
.catch(function (err) {
res.status(400).send(err);
});
}

How to update embedded document in mongoose?

I've looked through the mongoose API, and many questions on SO and on the google group, and still can't figure out updating embedded documents.
I'm trying to update this particular userListings object with the contents of args.
for (var i = 0; i < req.user.userListings.length; i++) {
if (req.user.userListings[i].listingId == req.params.listingId) {
User.update({
_id: req.user._id,
'userListings._id': req.user.userListings[i]._id
}, {
'userListings.isRead': args.isRead,
'userListings.isFavorite': args.isFavorite,
'userListings.isArchived': args.isArchived
}, function(err, user) {
res.send(user);
});
}
}
Here are the schemas:
var userListingSchema = new mongoose.Schema({
listingId: ObjectId,
isRead: {
type: Boolean,
default: true
},
isFavorite: {
type: Boolean,
default: false
},
isArchived: {
type: Boolean,
default: false
}
});
var userSchema = new mongoose.Schema({
userListings: [userListingSchema]
});
This find also doesn't work, which is probably the first issue:
User.find({
'_id': req.user._id,
'userListings._id': req.user.userListings[i]._id
}, function(err, user) {
console.log(err ? err : user);
});
which returns:
{ stack: [Getter/Setter],
arguments: [ 'path', undefined ],
type: 'non_object_property_call',
message: [Getter/Setter] }
That should be the equivalent of this mongo client call:
db.users.find({'userListings._id': ObjectId("4e44850101fde3a3f3000002"), _id: ObjectId("4e4483912bb87f8ef2000212")})
Running:
mongoose v1.8.1
mongoose-auth v0.0.11
node v0.4.10
when you already have the user, you can just do something like this:
var listing = req.user.userListings.id(req.params.listingId);
listing.isRead = args.isRead;
listing.isFavorite = args.isFavorite;
listing.isArchived = args.isArchived;
req.user.save(function (err) {
// ...
});
as found here: http://mongoosejs.com/docs/subdocs.html
Finding a sub-document
Each document has an _id. DocumentArrays have a special id method for looking up a document by its _id.
var doc = parent.children.id(id);
* * warning * *
as #zach pointed out, you have to declare the sub-document's schema before the actual document 's schema to be able to use the id() method.
Is this just a mismatch on variables names?
You have user.userListings[i].listingId in the for loop but user.userListings[i]._id in the find.
Are you looking for listingId or _id?
You have to save the parent object, and markModified the nested document.
That´s the way we do it
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Profile.findById(req.params.id, function (err, profile) {
if (err) { return handleError(res, err); }
if(!profile) { return res.send(404); }
var updated = _.merge(profile, req.body);
updated.markModified('NestedObj');
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, profile);
});
});
};