How to find documents with a combination of two fields in pymongo - mongodb

I have a collection which stores documents like this
{
// Other fields
'date':'07/01/2021',
'time':'09:21:10'
}
and I want to find documents greater than a specific date
yesterdays_date = (datetime.now() - timedelta(hours=24))
docs = db.collection.find({'date': {'$gte': yesterdays_date}}
How can I do that?

Ideally refactor your collection to store the date/times as a BSON date object; then your query would work.

you stored data like string :
{
// Other fields
'date':'07/01/2021', // => type = string
'time':'09:21:10' // => type = string
}
yesterdays_date // => returns datetime
if u wanna compare u should compare with datetime , not string with datetime
other problem is :
you should compare date with date ( not datetime format)

Related

How to convert and compare dates in spring mongodb data

I am trying to retrieve records from mongodb collection after certain date but the date field is stored as a string in mongodb collection. The below query doesn't work well I guess because it does a string comparison. How can I convert the string date from mongo and then compare with input date.
`mongoOperations.find(query(where("lastUpdated").gte(inputTimeStamp).and("status").in("COMPLETED")), Cart.class);`
Something like this worked for me. This may not be the best way to do it because it has potential of sql injection but I made sure data is sanitized before it reaches here.
String queryStr = "{\"$expr\": {\"$gte\": [{ \"$dateFromString\": { \"dateString\": \"$lastUpdated\",timezone:\"America/New_York\" }}, new Date(\"%s\") ]},status:{$in:[\"COMPLETED\"]}}";
BasicQuery query = new BasicQuery(String.format(queryStr,timeStamp));
return mongoTemplate.find(query, Cart.class);

How can I project date string or object instead of date number field in mongodb find query?

I have a date field that is javascript number date and I want to get the string or object of date (like new Date(date)) in find query projection instead of date field itself that is number.
//I want to get
datetime:new Date(date)
//instead of
db.myCollection.find({},{date:1})
thanks.
You can use forEach or map function
db.yourCollectionName.find({}).map(function(doc) {
return {
d:new Date(doc.datetime)
};
});

Construct Mongo ObjectId from timestamp with unique increment

I want to generate mongo objectid for the documents to be inserted as new with the timestamp value overwritten. so i used below code to get objectid.
var oIdWithTimestamp = function (timestamp) {
// Convert string date to Date object (otherwise assume timestamp is a date)
if (typeof (timestamp) == 'string') {
timestamp = new Date(timestamp);
}
// Convert date object to hex seconds since Unix epoch
var hexSeconds = Math.floor(timestamp / 1000).toString(16);
// Create an ObjectId with that hex timestamp
var constructedObjectId = mongoose.Types.ObjectId(hexSeconds + "0000000000000000");
return constructedObjectId
};
but if i want to insert 2 documents with same timestamp it doesn't fullfill the need. I noticed there is a get_inc function used to add incrementor value to objectids. And 16777214 different objectids can be generated using same timestamp. Any help regarding how to use this incrementor to get unique timestamp upto 16777214 is appreciated.
I have tried generating random mongo objectid using below snippet.
var bson = require('bson');
var generateObjIdFromTime = function(spefictime) {
spefictime = ~~(spefictime/1000);
return bson.ObjectID(spefictime);
}
It generates random mongo objectids with given timestamp.

How to sort this array of results?

Here is my query that attempts to sort an array of MongoDB documents based on a derived field called expiresAt. expiresAt is a Date object that represents the date string stored in doc.expirationDate.
It fails with an error TypeError: ... .sort({}) is not a function (shell):5
db.tokens.find().map(function(doc) {
var expiryDate = new Date(doc.credentialsMap.linkedin.expirationDate);
doc.expiresAt = expiryDate;
return doc;
}).sort({'expiresAt': -1});
What am I doing wrong? It's unclear to me exactly what return type map provides. If it's a cursor then why isn't sort supported? It's clearly available in the docs.
cursor.map() returns a Java script array.
The way you're calling sort() assumes that the return value is a MongoDB cursor, that's why it fails.
You'd have to use the regular Array.sort syntax.
For example, to have your map results sorted in descending order, use the following:
db.tokens.find().map(function(doc) {
var expiryDate = new Date(doc.credentialsMap.linkedin.expirationDate);
doc.expiresAt = expiryDate;
return doc;
}).sort(function(a,b) { return b.expiresAt - a.expiresAt});

Most efficient way to return document with highest DateTime value in field

I have a lucene's index with documents - all of them contain field that stores DateTime value. What would be recommended/most efficient way to extract document with highest value. How it would look like for integer values? Of course i am assuming that values are converted to string using DateTools.DateToString or similar methods.
Elaborating on Jf Beaulac answer, an example of such code may look like the one below. Please note that 'CreatedAt' field is used to store DateTime values.
//providing query that will not filter any documents
var query = new TermRangeQuery("CreatedAt", DateTools.DateToString(DateTime.MinValue, DateTools.Resolution.MINUTE), DateTools.DateToString(DateTime.MaxValue, DateTools.Resolution.MINUTE), false, false);
//providing sorting on 'CreatedAt' and returning just one result
var createdAtSerchResults = searcher.Search(query, null, 1, new Sort(new SortField("CreatedAt", SortField.LONG, true)));
//extracting CreatedAt value from returned document
var documentWithMaxCreatedAt = searcher.Doc(createdAtSerchResults.ScoreDocs.First().Doc);
var result = DateTools.StringToDate(documentWithMaxCreatedAt.Get("CreatedAt"));
Just issue a Query with a Sort descending on your field that contains the Date.
Use a Search method that takes a Sort in parameter, like this one:
IndexSearcher.Search(Query, Filter, int, Sort)