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)=>{
})
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 built an aggregate for searching according to a filter. The things that the user can search for are optional, So is there any way to make the match optional - for example the user can select a date, If he didn't select, I want the aggregate function not to use match date
db.articles.aggregate(
[ {
$match : { date : userSelectedDate }, { else : elseSelection}
} ]
);
If no date is selected => cancel the date matching and match anothers
I would try to build the query document dynamically.
var query = []
if (userSelectedDate){
query.push({ $match : { date : userSelectedDate }})
db.articles.aggregate(query)
The solution was in mongoose documentation using: Aggregate#append(ops)
Appends new operators to this aggregate pipeline
after having the aggregate
aggregate.append({ $project: { field: 1 }}, { $limit: 2 });
so now I can use if(condition) before appending
mongoose documentation for append
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" }}})
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