i'm working with nodejs server using mongoDB. Now i have a sample data:
{
"_id": ObjectId("555f1c0c7f4b820758b439b0"),
"user": "Guest1",
"friend": [{
"myfriend": "Guest2",
"info": []
}, {
"myfriend": "Guest3",
"info": []
}]
}
Now i want to put all "myfriend" into array, like this:
var listfriend = ["Guest2","Guest3"];
So how can i do it ?
Thank for read :)
Try using the map() method as follows:
var listfriend = db.names.findOne(
{"user" : "Guest1"},
{"_id": 0, "friend": 1}
).friend.map(function(obj){
return obj.myfriend;
});
console.log(listfriend); // ["Guest2","Guest3"]
Did you want to use the aggregation framework?
var aggregateFriends = function( db, callback)
{
db.collection('test').aggregate(
[
{ $unwind: "$friend" },
{ $group: { _id: "$user", friends: {$push: "$friend.myfriend" } } }
]
).toArray( function( err, result ) {
console.log(result);
db.close();
} );
};
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert')
var ObjectId = require('mongodb').ObjectID;
var url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
aggregateFriends( db, function() { db.close(); });
} );
Related
I'm trying to get the count of every distinct values from my mongodb, So far I can get the distinct values and count it.
How can I do this:
City Count
Pasig 22
Manila 12
Pasay 11
Sample document:
_id:5c1ca770385b472018874073
blood_product_donated:"Whole Blood"
branch:"Pasay"
deferral_type:"none"
deferral_date:"none"
So far here is what I did:
api.js
router.get('/blooddonationpie', function(req, res) {
Blooddonation.distinct('branch',function(err, branch) {
res.json({ success: true, branch: branch });
console.log(branch);
});
});
controller
angular.module('blooddonationControllers', [])
.controller('blooddonationCtrl', function(Blooddonation,$scope) {
var app = this;
function getChart() {
Blooddonation.getChart().then(function(data) {
app.branch = data.data.branch;
initChart();
});
}
function initChart() {
var data_series = [];
for(let key in app.branch) {
data_series.push({
"donor": app.branch[key],
"count": 501.9
});
}
var chart = AmCharts.makeChart( "chartdiv", {
"type": "pie",
"theme": "none",
"dataProvider": data_series,
"valueField": "count",
"titleField": "donor",
"balloon":{
"fixedPosition":true
},
"export": {
"enabled": true
}
});
}
This is the wrong output:
How can I get the count for each distinct values? Example Pasig: 21, Pasay: 22 etc.
You need to $group aggregation to get the count of each branches
db.col.aggregate([{$group: {_id : "$branch" , count :{$sum:1}}}])
{
"_id" : ObjectId("58d9084841a6168234689aee"),
"ID" : "01",
"data" : {
"Type1" : {
"value" : "ABC",
"timestamp" : "2017-03-20 16:01:01"
},
"Type2" : {
"value" : "ccc",
"timestamp" : "2017-03-20 16:01:01"
}
}
}
I want to get timestamp of each TYPE from mongodb using queryobject using nodejs.
How to get it,Please help.
var queryObject = url.parse(req.url,true).query;
var mdb = db.collection("HISTORY").find({{'timestamp':{"$gte":queryObject.fromdate,"$lt" : queryObject.todate}},{"ID":1});
Here is my node service:
function getHistory(req,res){
try{
var queryObject = url.parse(req.url,true).query;
var index=0, resultset = [];
var db1 = db.collection("HISTORY").find({$and : [{'data.Type1.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
{'data.Type2.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
{'data.Type3.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
{'data.Type4.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
{'data.Type5.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}}
]},{"Ino":1,"ID":1,"data":1});
db1.count(function(err, count) {
console.log("count" , count);
db1.each(function(err, doc) {
if(doc!=null){
var valdata=doc.alarms;
var fields = [];
var queryString ="SELECT field1,NAME FROM details c inner join locdetails l on c.loc_id=l.loc_id where no='"+doc.Ino+"' limit 1;";
var dtfield1 = null;
var dtfield2 = null;
connection.query(queryString, function(err,result){
index++;
if(err){
}else{
if(result.length>0)
{
dtfield1 = result[0].field1;
dtfield2 = result[0].NAME;
if(dtfield1!=null){
for (var x in valdata) {
var dt = new Date(valdata[x].timestamp).toISOString().replace(/T/, ' ').replace(/\..+/, '');
var compareDate = new Date(dt);
if(compareDate.getTime()>=fromDate.getTime()&&compareDate.getTime()<=toDate.getTime()){
resultset.push({"Name":dtfield1,"LName":dtfield2,"Ino":doc.Ino,"ID":doc.ID,"data":x,"datav":valdata[x].value,"Timestamp":valdata[x].timestamp});
}
if(index == count){
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.write(JSON.stringify(resultset));
res.end();
}
}} }}
});
} else {
}
});
});
}
catch (err) {
console.log("Exception -- ",err);
}
}
I want data should filter based on timestamp and same can be display in UI and download the displayed data.And also filter should be in UI like current day data and based on time filter also.
If you want search base on both Type1.timestamp and Type2.timestamp, you should use $and. you can change $and with $or if one matching one of them is enough
db.collection("HISTORY").find({
$and : [{'data.Type1.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}},
{'data.Type2.timestamp':{"$gte": new Date(queryObject.fromdate),"$lt" : new Date(queryObject.todate)}}
]
},
{ID:1}, function (err, res){
});
You can use aggregation to meet your requirements.
For your initial list which will only show the latest data values of each object, you can use the following pipeline -
[
{
$project:{
_id:1,
ID:1,
data:{ $objectToArray: "$data" }
}
},
{
$unwind:"$data"
},
{
$sort:{
"data.v.timestamp":-1
}
},
{
$group:{
_id:{
_id:"$_id",
ID:"$ID"
},
data:{
$first:"$data"
}
}
},
{
$addFields:{
data:["$data"]
}
},
{
$addFields:{
data:{ $arrayToObject: "$data" }
}
}
]
The result of the aggregation should give you an array of objects like this -
{
"_id" : ObjectId("5bc469c11f8e482416d6edb3"),
"ID" : "01",
"data" : {
"Type2" : {
"value" : "ccc",
"timestamp" : ISODate("2017-03-22T16:01:01.000+06:00")
}
}
}
As for filtering the collection to get documents with data properties that have timestamp values in the given range, the above pipeline can be modified to acquire it
[
{
$project:{
_id:1,
ID:1,
data:{ $objectToArray: "$data" }
}
},
{
$unwind:"$data"
},
{
$sort:{
"data.v.timestamp":-1
}
},
{
$match:{
"data.v.timestamp":{ $gt: "start date value", $lt: "end date value"}
}
},
{
$group:{
_id:{
_id:"$_id",
ID:"$ID"
},
data:{
$addToSet:"$data"
}
}
},
{
$project:{
_id:"$_id._id",
ID:"$_id.ID",
data:{ $arrayToObject: "$data" }
}
}
]
The result of this aggregation will produce array of objects similar to the one described above. But this time each document's data object will only have properties that match the timestamp condition.
Hope this helps. A final word of advice to you would be to rethink the schema design of the history collection. Because if simplistic date based queries are getting this difficult for you. You can only imagine what the future might hold for you with this design.
I am new in mongodb. I am simply insert the data using mongodb.My document looks:
{
"_id": ObjectId("5654085bf61deb761109d157"),
"address": "dsaddsadsad",
"email": "dsaddsadsad",
"name": "sadasdasdsad",
"__v": NumberInt(0)
}
My model looks:
// grab the mongoose module
var mongoose = require('mongoose');
// define our nerd model
// module.exports allows us to pass this to other files when it is called
module.exports = mongoose.model('users', {
name : {type : String, default: ''},
email : {type : String, default: ''},
address : {type : String, default: ''},
});
Now a user Comment on this.Then the document should be:
{
"comments": [
{
"uname": "arpit",
"uemail": "arpit#gmail.com",
"comment": "How can Make we this at good",
"posted_at": ISODate("2015-11-19T11:06:03.628Z")
},
{
"uname": "sumit",
"uemail": "sumit#ggi.net",
"comment": "this is also well for me",
"posted_at": ISODate("2015-11-19T11:06:27.172Z")
}
],
"_id": ObjectId("5654085bf61deb761109d157"),
"address": "dsaddsadsad",
"email": "dsaddsadsad",
"name": "sadasdasdsad",
"__v": NumberInt(0)
}
How can I make this document.My code is:
var Users = require("../app/models/users");
app.post('/comments/:id', function(req, res) {
var id = req.params.id; //coment id
var input = JSON.parse(JSON.stringify(req.body)); //comment data
//code should be here
});
Please help
/**users model*/
var mongoose = require('mongoose');
module.exports = mongoose.model('users', {
name : {type : String, default: ''},
email : {type : String, default: ''},
address : {type : String, default: ''},
comments: []
});
var Users = require("../app/models/users");
app.post('/comments/:id', function(req, res) {
var id = req.params.id; //coment id
var object = {}
for(var key in req.body){
object[key] = req.body[key];
}
Users
.findByIdAndUpdate(req.params.id, {$push: {"comments": object}})
.exec(function(error, result){
if(error){
console.log(error);
}
else{
console.log(result);
}
})
Test this:
Users.findByIdAndUpdate(id, {$push: {"comments":{
uname: req.body.the_uname,
uemail : req.body.the_uemail,
comment: req.body.the_comment,
posted_at: Date.now()
}
}
}).exec(function(error, res){});
my schema looks like this:
var exampleSchema = newSchema({
profile:{
experience :[{
exp : String
}]
}
});
this is the codes to update experience in profile collection:
exampleSchema.statics.experience = function (id,experience, callback){
var update = {
$push: {
'profile.experience': experience
}
}
this.findByIdAndUpdate(id,update,function(err) {
if (err) {
callback(err);
} else {
callback(null);
}
})
I was getting error like The field 'profile.experience' must be an array but is of type String in document {_id: ObjectId('5653f1d852cf7b4c0bfeb54a')}[object Object]
console.log(experience) is equal to
{ exp: 'jlkjlkjlk' }
my collection should look like this:
experience:[
{
exp : "YYYY"
},
{
exp:"xxxx"}
]
Imagine that you have this collection:
/* 1 */
{
"_id" : ObjectId("565425e862760dfe14339ba8"),
"profile" : {
"experience" : [
{
"exp" : "Experto"
}
]
}
}
/* 2 */
{
"_id" : ObjectId("565425f562760dfe14339ba9"),
"profile" : {
"experience" : {
"exp" : "Experto"
}
}
}
/* 3 */
{
"_id" : ObjectId("5654260662760dfe14339baa"),
"profile" : {
"experience" : "Experto"
}
}
If you try (update doc /* 2 */):
db.profile.update(
{ _id: ObjectId("565425f562760dfe14339ba9") },
{ $push: { "profile.experience" : { exp : "Intermediate" } } }
)
You get this error:
The field 'profile.experience' must be an array but is of type Object
in document {_id: ObjectId('565425f562760dfe14339ba9')}
And if you try (update doc /* 3 */):
db.profile.update(
{ _id: ObjectId("5654260662760dfe14339baa") },
{ $push: { "profile.experience" : { exp : "Intermediate" } } }
)
You will get:
The field 'profile.experience' must be an array but is of type String
in document {_id: ObjectId('5654260662760dfe14339baa')}
i changed Schema like this
experience : [{type:String,exp:String}],
my update object looks like this
var update = {
$push: {
'profile.experience': san.exp
}
};
san looks like this :{ exp: 'YYY' }
Inside mongoose collectionlooks like this used RoboMongo
"experience" : [
"experienced in XXX",
"YYY"
],
$push: {
'profile.experience': experience
}
Remove .exp.
First you have to check you declared your field as an array like this(look at field products):
shop = {
'name': "Apple Store",
'description': "",
'direction': "",
'contact': "",
'products':[]
}
Now if you want to add something to the field products using $push
product = {
'name': "Iphone 6",
'description': "Iphone model 6, 64GB",
'price': 700,
'count': 3
}
myquery = { "name" : "Apple Store" }
obj ={"$push":{"products":{"$each": [product]}}}
db.collection.update_one(myquery,obj)
This code is provided for PyMongo framework. To use in MongoDB directly replace update_one by update. Mongo resource
You may use $set instead of $push which might work.
$set: {
'profile.experience': experience
}
are you searching for adding multiple values into single field then use this one.
write this one your model or schema:
arrayremarks:[{remark: String}]
then write in your controller:
module.exports.addingremarks = (req, res) => {
let casenum=JSON.parse(JSON.stringify(req.body.casenum).replace(/"\s+|\s+"/g,'"'))
var rem={remark:"Suman macha"}
Inwart.update( { 'casenum': casenum },{ $push: { arrayremarks:rem} } ,function (err, inwarts) {
if (err)
return console.error(err);
res.send(inwarts);
}
)
}
I'm trying to insert documents in an array using Mongoose.
Here's the Schema:
var user = new mongo.Schema({
_id : Number,
devices:[
{
device_id : String,
type : String
}
]})
The update code in NodeJS looks like:
app.put('/user/update',function(req,res){
var obj = req.body;
users.update(
{'user.username' : obj.email},
{
'user.username' : obj.email,
'user.password' : obj.password,
'user.name.first' : obj.name,
'user.department' : obj.department,
'user.year' : obj.year,
'user.college' : obj.college,
'user.contact.phone': obj.contact,
'user.last_login' : obj.last_login,
$push:{
'devices': {
device_id: 'sadasd32u4je3bdjas',
type: 'Windows'
}
}
}, function(err){
if(err)
res.json({"foo": String(err)});
else
res.json({"foo": "Successfully Signed up!"});
});
}
);
But instead it inserts something like:
"devices": [
"[object Object]",
"[object Object]",
"[object Object]",
"[object Object]",
"[object Object]"
],
Where did I go wrong? Thanks again.
Use the findOneAndUpdate() method with the 'upsert' option set to true - this creates the object if it doesn't exist (defaults to false):
var obj = req.body;
var query = {'user.username': obj.email};
var doc = {
$set: {
'user.username': obj.email,
'user.password': obj.password,
'user.name.first': obj.name,
'user.department': obj.department,
'user.year': obj.year,
'user.college': obj.college,
'user.contact.phone': obj.contact,
'user.last_login': obj.last_login
},
$push: {
'devices': {
device_id: 'sadasd32u4je3bdjas',
type: 'Windows'
}
}
};
var options = {upsert: true};
users.findOneAndUpdate(query, doc, options, function(err){
if(err)
res.json({"foo": String(err)});
else
res.json({"foo": "Successfully Signed up!"});
});