I have many number of documents in my collection i want to save same data by changing only one field i.e. "date" (which will be current time) repeatedly in the Mongo database.so how can i do this in mongodb.
You can use $set operator to update only one filed of your document. You don't need to rewrite whole document:
collection.update({"_id": docId}, {$set: {"date": someDate }})
Consider also to use $currentDate operator if you want to set some field to current date value:
collection.update({"_id": docId}, {$currentDate: {"date": true }})
// or
collection.update({"_id": docId}, {$currentDate: {"date": { "$type": "timestamp" }}})
Related
I have several documents on MongoDB collection that were created with an invalid date value and have it currently as:
"UpdateDate " : Date(-62135596800000)
I want to filter those documents, but my query is not returning any data:
db.MyCollection.find({UpdateDate : Date(-62135596800000)})
How can I filter my collection to retrieve those documents?
The problem with your query is that you need to build a proper Date object. This may be different depending on what languaje or drivers are you using to query, but in JS just using new Date() should work.
db.MyCollection.find({UpdateDate : new Date(-62135596800000)})
If you cant reproduce what the value need to be , luckily the date when you have inserted the document for the first time you can extract and update from the document _id as follow:
db.getCollection('MyCollection').update({ UpdateDate : new Date(-62135596800000)
},
[
{ "$set": { "UpdateDate": { $toLong: { $toDate: "$_id" }}}}
],
{ "multi" : true}
)
This is with the assumption that you havent customized the default _id
I Have a mongodb with objects like this:
{
"_id" : "7XXXXXXXXXX",
"apps" : [
{
"id" : "e0d538e0df9a345e",
"os" : "android",
"token" : "f1zp-VSi7Ec:APA91bEAbfH8nMeVidkIjPrJ28WHRFDy-BhvKCQdDSdCYsylUzET9GjbPHjofCrr1NMQurinMCI4fuiF7VWNPXne-80op_h0MloK217kc1zKptdo9FTgAH5R932uDphcyB1xQ27-AFdR",
"version" : "3.2.1",
"build" : "8115680e",
"timestamp" : NumberLong(1571740696818)
}
]
}
How i can select objects older certain date using timestampin my case, for example older 3 month?
You can use $toDate operator in aggregation to do the desired operation,
I hope you are using mongo version 4.0+
$toDate is supported in mongo version 4.0 and on
let selectedDate = new Date();
selectedDate.setDate(d.getDate()-30); //subtracting 30 days from today's date
db.collection("your_collection_name").aggregate({$unwind:{ path: "$apps"}},
{$addFields: { dateValue: {$toDate: "$apps.timestamp" }}},
{$match: { dateValue: {$lte: selectedDate }}},
(err, result) => {
//perform your desired operations
});
Explanation:
basically, I am first unwinding apps array, which will result in having a separate document of each entry in apps.
Then operate on the timestamp field in each document, and convert it into a proper date with $toDate.
Then in the next stage apply your filter with $match.
UPDATE (from comments):
as you are using mongo version 3.2 the above solution will not work.
then I think, you can opt for another approach here:
Query all your documents in this particular collection, find the proper date from the timestamp field.
Update each document with a new field which will now have the value of computed date from the above step, and save it.
I suggest you write a migration script for the above two steps.
Make sure when inserting a new document, you already add this newly computed date field.
Then you can have simple query like:
db.collection("your_collection_name").find({"app.newDateField": {$lte: {selectedDate }}},
{ "apps.$": 1},
(err, result)=>{
})
Considering a MongoDB Document as following
{
"_id": ObjectId("59f05fd6aa6e2bdef4275ebb"),
"property": "example value",
"updatedAt": ISODate("2018-07-14T01:00:00+01:00"),
"createdAt": ISODate("2018-07-15T01:00:00+01:00"),
"deletedAt": ISODate("2018-07-16T01:00:00+01:00")
}
My questions are about MongoDB best practices and especially minimising response time and indexing costs.
Since creation timestamp is encoded in _id and queryable with comparison operators ($gt(e), $lt(e) ...) (see this post) : what's the most performant between directly querying "_id" property and consequently keeping _id the only collection's index and adding ISODate field createdAt and also indexing this field ?
Finally, how to choose between indexing a single property (deletedAt) or combining them (_id, deletedAt) knowing that the most frequent query will be something like that
db.myCollection.find({
deletedAt: { $exists: false },
_id: { $gt: ObjectId('somepastobjectid') }
})
Note that _id is indexed by default and I just need to check existence of deletedAt (the value will be used very occasionally)
Thank you for your answers
I know how to sort documents using MongoDB. But I want to sort documents over multiple date attributes like sort on created and updated date which one is latest. For example document is newly created or recently updated, it should be come first.
here is my document sample.
{
"_id" : ObjectId("5720b6f0bb700f8839fc6972"),
"name" : "Tov Kosher Kitchen",
"restaurant_id" : "40356068",
"createdAt" : ISODate("2016-05-05T07:02:13.137Z"),
"updatedAt" : ISODate("2016-05-05T07:02:58.033Z")
}
Update: createdAt and updatedAt are sample attributes. Both can be changed independent of each other.
You can do this with aggregate by using a $project stage that adds a field which is the greater of the two timestamps and then sorting on that:
db.test.aggregate([
{$project: {
// Include the original doc
doc: '$$ROOT',
// Add a 'latest' field that contains the greater of createdAt and updateAt
latest: {$cond: {
if: {$gt: ['$createdAt', '$updatedAt']},
then: '$createdAt',
else: '$updatedAt'
}}
}},
{$sort: {latest: -1}}
])
Can you set both the "updatedAt" date and "createdAt" date when the document is created (or when the createdAt date is set). Then you can just sort by updatedAt.
Since this can't be done with a sort, another option you have is writing a script that compares updatedAt and createdAt for each document and writes a new property to the document called "mostRecentDate" which is the most recent date of updatedAt and createdAt.
Then sort by "mostRecentDate," make sure any future writes or updates changes this property and other date property.
I wanted to find data for 2014-08-01 from MongoDB collection. Date in MongoDB is in ISO format.I wrote below query, but it gives me very huge number which i suspect is not the data for 1 day. Can some one let me know what is wrong with query.
sd is the key
db.history.count({sd:{$gte: new Date("2014-08-01")},sd:{$lt:new Date("2014-08-01")}})
Ranges can be specified using $gte and $lt in the same document portion:
db.history.count({ "sd": {
"$gte": new Date("2014-08-01"), "$lt": new Date("2014-08-02")
}})
Otherwise the argument are considered to be separate and a logical "and" condition. But really since you are using the same "key" in your "sd" field, this is not allowed in a JSON/BSON document and violates the "unique" keys rule for hash structures in general. So one condition overwrites the other and only one is applied.
That is why your result is wrong. Use as shown above instead.
await model.find(
{
$or:
[
{
createdDate:
{ $gte: new Date(startDate), $lte: new Date(endDate) },
},
{
createdDate:
{ $gte: new Date(startDate), $lte: new Date(endDate).setDate(new Date(endDate).getDate() + 1) },
},
],
},
)
Please assign value to startDate and endDate. The above example will help to find different data from different date as well as the same date
for example if your trying to fetch data from '2020-06-22' to '2020-07-02' you will get data from this date range, other your are trying to fetch data on the same date this code will work that mechanism also
Thank you