push data to multidimensional mongodb document - node.js

Hi I have multi dimensional mongoDB document now I want to push new records to the locations filed with same objects time , lat , lng
here is my database record
{
"_id" : ObjectId("5979b1a81c4547652583397e"),
"shenase" : "002",
"name" : "??? ?????",
"vehicle" : "?????",
"locations" : {
"time" : "2017-07-27 13:55:30",
"latiude" : 35.7429305,
"langtiude" : 51.5001943
}
}
I want to know how can I do that with node js

Firstly your database schema is not correct. Locations must be an array and not an object. So the record must be
{
"_id" : ObjectId("5979b1a81c4547652583397e"),
"shenase" : "002",
"name" : "??? ?????",
"vehicle" : "?????",
"locations" : [
"time" : "2017-07-27 13:55:30",
"latiude" : 35.7429305,
"langtiude" : 51.5001943
]
}
Now to push the new record onto array you can simply write
var data = {
"time":"2017-07-29 13:55:30",
"latitude": 18.0667,
"longitude": 45.99890
};
YourModel.update(
{ _id: toBeUpdated._id },
{ $push: { location: data } },
function(err,data){
console.log(err,data);
}
);

Related

How to delete an nested object based on its ObjectId?

I have this nested Schema for my courses collections, there is a sessions array in every course and a students array in every session and every student is an object consisting of a property of userName with a value of ObjectId refering to my users collections and another property names status containing some number.
I want to delete an student object from my students array of my session with its _id.
I know it is possible to unwind arrray to get to a single object but I need a neat way like using an objectId to delete an object from database so that we don't have to specify path like directly deleting or modifying that nested subdocument.
This is my course schema:
CourseSchema = new mongoose.Schema({
name:String,
sessions:[
{
date:Date,
students :[{
userName:{
type:mongoose.Schema.Types.ObjectId,
ref :'users'
},
status:Number
}]
}
]
})
You can use the following DELETE route to delete a student from a course session.
router.delete(
"/course/:courseId/session/:sessionId/student/:studentId",
async (req, res) => {
try {
let result = await Course.updateOne(
{ _id: req.params.courseId, "sessions._id": req.params.sessionId },
{
$pull: { "sessions.$.students": { userName: req.params.studentId } }
}
);
res.send(result);
} catch (err) {
console.log(err);
res.status(500).send("Something went wrong");
}
}
);
Let's say you have a course like this:
{
"_id" : ObjectId("5de907acdfcef9493cd215a8"),
"name" : "Course 1",
"sessions" : [
{
"date" : ISODate("2019-12-05T16:32:41.998+03:00"),
"_id" : ObjectId("5de907acdfcef9493cd215a9"),
"students" : [
{
"_id" : ObjectId("5de907acdfcef9493cd215ac"),
"userName" : ObjectId("5de8e4c8f74cf254d04f90d8"),
"status" : 1
},
{
"_id" : ObjectId("5de907acdfcef9493cd215ab"),
"userName" : ObjectId("5de8e4d5f74cf254d04f90d9"),
"status" : 1
},
{
"_id" : ObjectId("5de907acdfcef9493cd215aa"),
"userName" : ObjectId("5de8e4ddf74cf254d04f90da"),
"status" : 1
}
]
}
],
"__v" : 0
}
If we want to delete the student with userName with value 5de8e4ddf74cf254d04f90da, we can send a DELETE request to our route using an url like this:
http://localhost/courses/5de907acdfcef9493cd215a8/session/5de907acdfcef9493cd215a9/student/5de8e4ddf74cf254d04f90da
5de907acdfcef9493cd215a8--> courseId
5de907acdfcef9493cd215a9--> sessionId
The response will be like this:
{
"n": 1,
"nModified": 1,
"ok": 1
}
When we look at our course, we see the student is removed:
{
"_id" : ObjectId("5de907acdfcef9493cd215a8"),
"name" : "Course 1",
"sessions" : [
{
"date" : ISODate("2019-12-05T16:32:41.998+03:00"),
"_id" : ObjectId("5de907acdfcef9493cd215a9"),
"students" : [
{
"_id" : ObjectId("5de907acdfcef9493cd215ac"),
"userName" : ObjectId("5de8e4c8f74cf254d04f90d8"),
"status" : 1
},
{
"_id" : ObjectId("5de907acdfcef9493cd215ab"),
"userName" : ObjectId("5de8e4d5f74cf254d04f90d9"),
"status" : 1
}
]
}
],
"__v" : 0
}
As we see the student with username with value 5de8e4ddf74cf254d04f90da does not exists anymore in the course session, meaning it is removed.

how to group records based on dates in mongodb

How to group data by dates? I have some docs in mongo that looks something like this: yes i have added my actuall mongo doc and my code too
{
"_id" : ObjectId("58c0e32161ccc654160b776a"),
"consumer_id" : ObjectId("579f03069b49a0840409df83"),
"user_id" : "579f034c9b49a0840409df85",
"values" : [
{
"date" : "2017/2/9",
"point" : 1
},
{
"date" : "2017/2/10",
"point" : -1
},
{
"date" : "2017/2/11",
"point" : -1
}
]
}
{
"_id" : ObjectId("58c0e3db61ccc654160b776b"),
"consumer_id" : ObjectId("579f03069b49a0840409df83"),
"user_id" : "579ef6f5a15b0eac1332034e",
"values" : [
{
"date" : "2017/2/9",
"point" : 1
},
{
"date" : "2017/2/10",
"point" : 1
},
{
"date" : "2017/2/11",
"point" : -1
}
]
}
I'd like to be able to count the no of points by date
my code is like this
var array = [];
var array2 = [];
db.coll.find({}).toArray(function(err, result) {
result.map(function(data) {
array.push(data.values)
})
You would use following :
db.your_collection.aggregate([
{ $unwind : '$values'},
{ $group : {
_id : '$values.date',
point : { $sum : '$values.point' }
}
}
]);
Which will give you below result :
{ "_id" : "2017/2/11", "point" : -2 }
{ "_id" : "2017/2/10", "point" : 0 }
{ "_id" : "2017/2/9", "point" : 2 }
However, its always good to have date stored in proper date format and not as a string.
You need to use the sort function from mongodb:
sort({datefield: -1}}
in Mongodb for example
db.products.find().sort({"created_at": 1}) --- 1 for asc and -1 for desc
in nodejs for example:
collection.find().sort({datefield: -1}, function(err, cursor){...});
You need to perform a map/reduce
I assume your array of objects are stored in the data field of your documents, themselves in an items collection.
// map function which pushes the points in an array associated to the given date date
var mapDataPoints = function() {
for (var i=0; i<this.data.length; i++) emit(this.data[i].date, this.data[i].points);
};
// reduce function, which sums the array of points for a given date
var reduceDataPoints = function(dateId, points) {
return Array.sum(points);
};
// map-reduce operation over the collection, which takes each document and apply the map function, then run the reduce function on the result of the map operation
// result is stored in a new collection, called pointsByDate
db.items.mapReduce(
mapDataPoints,
reduceDataPoints,
{ out: "pointsByDate" }
)
// pointsByDate can be queried just like any collection
db.pointsByDate.find({ "_id": "2017/2/10" });
The following code works for your problem.
db.Stack.aggregate([
{$unwind: "$values"},
{$group: {
_id: "$values.date",
sum: {$sum: "$values.point"}
}
}
])
This is the output for your code
/* 1 */
{
"_id" : "2017/2/11",
"sum" : -2.0
}
/* 2 */
{
"_id" : "2017/2/10",
"sum" : 0.0
}
/* 3 */
{
"_id" : "2017/2/9",
"sum" : 2.0
}

Mongoose array of objects query by slug

I am trying to make a query for documents that have an array of objects like this. its a history of when a tag was added.
{
"added_by" : ObjectId("58d92d8b11af264b87a8f5d4"),
"tag" : ObjectId("58d92d8b11af264b87a8f5ed"),
"_id" : ObjectId("58d92d8c11af264b87a8f6d5"),
"added_at" : ISODate("2017-03-02T22:06:42.788Z")
}
I am not able to make the query on the slug just the _id
I have tried this:
var query = {
'tags.tag': {
slug: $in: ['tag-name']
}
}
Node.find(query, (err, nodes) => {
if (err) {
res.status(404)
res.send(err)
} else {
res.json(nodes);
}
}).populate(['tags.tag'])
Here is the document:
{
"_id" : ObjectId("58d92d8c11af264b87a8f6d0"),
"user_id" : ObjectId("58d92d8b11af264b87a8f5d4"),
"uid" : "-KeG2FvL0jwkHFvOautH",
"updated_at" : ISODate("2017-03-02T22:06:42.788Z"),
"created_at" : ISODate("2017-03-02T22:06:42.051Z"),
"tags" : [
{
"added_by" : ObjectId("58d92d8b11af264b87a8f5d4"),
"tag" : ObjectId("58d92d8b11af264b87a8f5ed"),
"_id" : ObjectId("58d92d8c11af264b87a8f6d5"),
"added_at" : ISODate("2017-03-02T22:06:42.788Z")
},
{
"added_by" : ObjectId("58d92d8b11af264b87a8f5d4"),
"tag" : ObjectId("58d92d8b11af264b87a8f626"),
"_id" : ObjectId("58d92d8c11af264b87a8f6d4"),
"added_at" : ISODate("2017-03-02T22:06:42.788Z")
}
],
"status" : "publish",
"description" : "some text here",
"title" : "Anna James",
"__v" : 0
}
Any thoughts?
Since you store references to tags, you need to fetch the tag by slug first:
TagsCollection.find({slug:'tag-name'}, (err, tags)...)
then filter by tag._id:
var query = {
'tags.tag': new ObjectId(tag._id)
}
or
var query = {
'tags.tag': {'$in": [new ObjectId(tag._id), ....]}
}
if you have more than 1 tag matching the slug.
Honestly, it would be way more efficient, if you store tags directly in the document, instead of storing references.

How to remove a document from a deep collection using mongodb query?

{
"_id" : ObjectId("5728443e04b2e5b42073a361"),
"user_id" : ObjectId("5728443e04b2e5b42073a35f"),
"main" : {
"data_to_save" : [
{
"user_profile_id" : ObjectId("572844bc04b2e5b42073a362")
"_id" : ObjectId("57284ab183e62da222e1378b"),
"details" : [
{
"amount" : 10000,
"_id" : ObjectId("57284f42e4560b66238a637c"),
"modified" : ISODate("2016-05-03T12:42:02.927Z"),
"created" : ISODate("2016-05-03T12:42:02.927Z")
},
{
"amount" : 4000
"_id" : ObjectId("57284f42e4560b66238a637b"),
"modified" : ISODate("2016-05-03T12:42:02.927Z"),
"created" : ISODate("2016-05-03T12:42:02.927Z")
}
]
}
]
}
"__v" : 0
}
In database schema of mongoDB. Here I am want to remove perticular document of a perticular collection.
like I want to remove first document of details collection. I have _id ( 57284f42e4560b66238a637c ) of that perticular document.
Tried
connection.collection.remove( { 'main.data_to_save.0.details.$._id' : id }, function ( err, removed ) {});
You could use the $pull operator to remove one or more entries from an array of documents:
// mainDocId = ObjectId("5728443e04b2e5b42073a361")
// id = ObjectId("57284f42e4560b66238a637c")
connection.collection.update(
{ _id: mainDocId},
{ $pull: {'main.data_to_save.0.details' : id } }, function ( err, result ) {
});

Query sub documents in mongoose

I am new to node.js.
I am having JSON object of the form
{ "_id" : ObjectId("540b03ddf1768fe562fbb715"),
"productid" : "men1",
"comments" : [ { "name" : "shiva", "text" : "Haidddsdcccccc", "_id" : ObjectId("540b03dd0570a6261e20a59e"), "date_entered" : ISODate("2014-09-06T12:53:49.658Z") },
{ "name" : "shiva", "text" : "Haidddsdcccccc", "_id" : ObjectId("540cb2be35f8145a2d296ea0"), "date_entered" : ISODate("2014-09-07T19:32:14.827Z") },
{ "name" : "shiva", "text" : "Haidddsdcccccc", "_id" : ObjectId("540cb2c335f8145a2d296ea1"), "date_entered" : ISODate("2014-09-07T19:32:19.456Z") } ] }
I want to query comments of a product after a specific time
I am using query as
var query=Product.find({"productid":obj.productid,
'comments.date_entered': {$gt: obj.timed}}, {'comments.$': 1})
I am getting only one object after the specific time i.e
{
_id: "540b03ddf1768fe562fbb715"
comments: [1]
0: {
name: "shiva"
text: "Haidddsdcccccc"
_id: "540cb2be35f8145a2d296ea0"
date_entered: "2014-09-07T19:32:14.827Z"
}
}
How to get all the comments of the product after the specified time?
Doesn't seem to be a good way to do this from what I can find out. A work-around could be doing something like this:
Product.findOne({productid: PRODUCT_ID}, {comments: 1}, function(err, product) {
var comments = product.comments.filter(function(comment) {
return comment.date_entered > DATE;
});
...
})

Resources