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);
Related
I'm using PrestoDB to query some MongoDB collections. MongoDB has a getTimestamp() method to get the timestamp portion of an ObjectId. How can I get a similar timestamp on PrestoDB?
It's not implemented in Presto, but there is a PR: https://github.com/prestosql/presto/pull/3089
You can implement this with eg
#ScalarFunction("get_timestamp")
#SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) // ObjectId's timestamp is a point in time
public static long getTimestamp(#SqlType("ObjectId") Slice value)
{
int epochSeconds = new ObjectId(value.getBytes()).getTimestamp();
return DateTimeEncoding.packDateTimeWithZone(TimeUnit.SECONDS.toMillis(epochSeconds), UTC_KEY);
}
-- add this in the https://github.com/prestosql/presto/blob/master/presto-mongodb/src/main/java/io/prestosql/plugin/mongodb/ObjectIdFunctions.java class
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)
};
});
Query to fetch records for time range of 10 seconds is fetched properly in mongo shell using below:
db.getCollection('collection-name').find({"#timestamp":{"$gte": ISODate("2018-02-07T01:51:45.005Z"),"$lt": ISODate("2018-02-07T01:51:55.005Z")}});
But in spring-data-mongodb I am unable to get the data using below methods. Either I am not able to define ISODate("String value") or new Date("String value") in #Query annotation or mongo query criteria.
Method 1: Mongo Repository & Query
#Query("{'#timestamp' :{'$gte':?0, '$lt':?1}}")
public List<collection-name> findByTimestamp( Date date,Date newdate);
Method 2: Using Mongo Query with criteria
Query query = new Query();
query.addCriteria(Criteria.where("#timestamp").gte( date).lt(newdate));
where date and new date fields are:
DateFormat df=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS\'Z\'");
Date date = df.parse("2018-02-07T01:51:45.005Z");
Date newdate = df.parse("2018-02-07T01:51:55.005Z");
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)
I need to iterate through all of the collections in my MongoDB database and get the time when each of the collections was created (I understand that I could get the timestamp of each object in the collection, but I would rather not go that route if a simpler/faster method exists).
This should give you an idea of what I'm trying to do:
MongoDatabase _database;
// code elided
var result = _database.GetAllCollectionNames().Select(collectionName =>
{
_database.GetCollection( collectionName ) //.{GetCreatedDate())
});
As far as I know, MongoDB doesn't keep track of collection creation dates. However, it's really easy to do this yourself. Add a simple method, something like this, and use it whenever you create a new collection:
public static void CreateCollectionWithMetadata(string collectionName)
{
var result = _db.CreateCollection(collectionName);
if (result.Ok)
{
var collectionMetadata = _db.GetCollection("collectionMetadata");
collectionMetadata.Insert(new { Id = collectionName, Created = DateTime.Now });
}
}
Then whenever you need the information just query the collectionMetadata collection. Or, if you want to use an extension method like in your example, do something like this:
public static DateTime GetCreatedDate(this MongoCollection collection)
{
var collectionMetadata = _db.GetCollection("collectionMetadata");
var metadata = collectionMetadata.FindOneById(collection.Name);
var created = metadata["Created"].AsDateTime;
return created;
}
The "creation date" is not part of the collection's metadata. A collection does not "know" when it was created. Some indexes have an ObjectId() which implies a timestamp, but this is not consistent and not reliable.
Therefore, I don't believe this can be done.
Like Mr. Gates VP say, there is no way using the metadata... but you can get the oldest document in the collection and get it from the _id.
Moreover, you can insert an "empty" document in the collection for that purpose without recurring to maintain another collection.
And it's very easy get the oldest document:
old = db.collection.find({}, {_id}).sort({_id: 1}).limit(1)
dat = old._id.getTimestamp()
By default, all collection has an index over _id field, making the find efficient.
(I using MongoDb 3.6)
Seems like it's some necroposting but anyway: I tried to find an answer and got it:
Checked it in Mongo shell, don't know how to use in C#:
// db.payload_metadata.find().limit(1)
ObjectId("60379be2bec7a3c17e6b662b").getTimestamp()
ISODate("2021-02-25T12:45:22Z")