Most efficient way to return document with highest DateTime value in field - lucene.net

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)

Related

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

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)

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 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});

How to pass variable between two queries in MongoDB?

I want to put the query result from one collection in a variable and use it as input for query in another collection. The queries look like this as follows:
Query 1:
var ID=db.User.findOne({Name:"Ivan"}, {ID: 1});
db.Artists.find({"Listeners.ID":ID});
Query 2:
var Friends=db.Users.find({Friends:x});
//Users.Friends is an array of interger identifier for User
db. Artists.find({"Listeners.ID":{$in:Friends}});
But they all don't work. How to write the right one?
The query db.User.findOne({Name:"Ivan"}, {ID: 1}); does not return a single value, it returns the document, reduced to the field you requested. What you get is an object, with two fields: _id (because you didn't explicitly exclude it) and ID (when it exists in the document). Your var ID looks like this:
{
_id:ObjectId(<long hex string>),
ID:<value>
}
So when you want to query by the ID value, you need to specify it:
db.Artists.find({"Listeners.ID":ID.ID});
Regarding your second query: when you use find instead of findOne you get a cursor object which can then be used to retrieve the individual documents using cursor.next() or cursor.toArray().

Composite views in couchbase

I'm new to Couchbase and am struggling to get a composite index to do what I want it to. The use-case is this:
I have a set of "Enumerations" being stored as documents
Each has a "last_updated" field which -- as you may have guessed -- stores the last time that the field was updated
I want to be able to show only those enumerations which have been updated since some given date but still sort the list by the name of the enumeration
I've created a Couchbase View like this:
function (doc, meta) {
var time_array;
if (doc.doc_type === "enum") {
if (doc.last_updated) {
time_array = doc.last_updated.split(/[- :]/);
} else {
time_array = [0,0,0,0,0,0];
}
for(var i=0; i<time_array.length; i++) { time_array[i] = parseInt(time_array[i], 10); }
time_array.unshift(meta.id);
emit(time_array, null);
}
}
I have one record that doesn't have the last_updated field set and therefore has it's time fields are all set to zero. I thought as a first test I could filter out that result and I put in the following:
startkey = ["a",2012,0,0,0,0,0]
endkey = ["Z",2014,0,0,0,0,0]
While the list is sorted by the 'id' it isn't filtering anything! Can anyone tell me what I'm doing wrong? Is there a better composite view to achieve these results?
In couchbase when you query view by startkey - endkey you're unable to filter results by 2 or more properties. Couchbase has only one index, so it will filter your results only by first param. So your query will be identical to query with:
startkey = ["a"]
endkey = ["Z"]
Here is a link to complete answer by Filipe Manana why it can't be filtered by those dates.
Here is a quote from it:
For composite keys (arrays), elements are compared from left to right and comparison finishes as soon as a element is different from the corresponding element in the other key (same as what happens when comparing strings à la memcmp() or strcmp()).
So if you want to have a view that filters by date, date array should go first in composite key.