hibernate query builder for lucene time range - lucene

I am building a lucene query for an indexed object to determine if current time lies between the range of start Time and end Time. I'm unable to get the exact lucene query .
org.apache.lucene.search.Query luceneQuery5=queryBuilder3.bool()
.must(queryBuilder3.keyword().onFields("TimeDependentProfileKey").matching("TimeKey").createQuery())
.must(queryBuilder3.range().onField("StartTime").above(new Time(0)).createQuery())
.must(queryBuilder3.range().onField("StopTime").below(new Time(0)).createQuery()).createQuery();`
The lucene query which was generated looks like:
+TimeDependentProfileKey:3 +StartTime:[19700101000000000 TO *] +StopTime:[* TO 19700101000000000]
how do i change the format of timestamp, can anyone please help me.

By searching for a date object, you are deferring formatting to hibernate. I would consider the format you specified as functional, though perhaps not ideal. If you want to use your own formatting, you must deal in strings, be consistent in your formatting, and make sure your format will work well for sorting and range queries as a string.
If you want to have hibernate handle formatting dates for you, you need to define your date field with a #DateBridge(resolution = ...) annotation. This ensures that hibernate will format dates effective for correct range querying and sorting in lucene, and allows you to query against the field with date objects instead of strings.

Related

Why would SQL statement return out of ordered dataset?

I have written a program that logs events into a db file as they happen using SQL statement. Whenever I open the table to view, I specifically request the dataset in descending order based on ALARM's date and time. It seems to work only for part of the table. I am using SQLite3 and my program is written in delphi or Pascal.
Here is the SQL statement:
SELECT *
FROM Alarms
ORDER BY datetime(ALARMTIME) DESC
Here is a snapshot of the table. Pay attention to the red arrows. That's where Alarm's date and time doesn't follow descending order. I don't know why this is happening.
I'm not sure how you created your date/time string in your database since that information wasn't given in the question. However, according to the documentation for the datetime() function, the format you have of MM/DD/YYYY HH:MM:SS xx is not one of the accepted formats. In fact, if you do SELECT datetime('1/23/2018 01:40:00 PM') at an SQLite prompt, you get NULL. Whereas, if you use an acceptable format, you do not: SELECT datetime('2018-01-23') gives '2018-01-23 00:00:00'.
So I think the solution is to write the ALARMTIME field using datetime('now'), which does yield a format accepted by datetime(). If you need to sort based upon the format you have now, you can't do it with datetime(). You'd need to reformat the field using string functions to get it in a form you could do a string compare with (e.g., as is done here).
The OP has indicated in a comment that the ALARMTIME is set using the following Pascal code:
FieldByName('AlarmTime').AsDateTime := now;
There's no guarantee that Pascal is going to use a date/time string format in this context that is compatible with SQLite's datetime() function. So Pascal date/time formatting functions can be used to create a format more specifically acceptable by SQLite's datetime(). Then you'd use something like:
FieldByName('AlarmTime').AsString := FormatDateTime('YYYY-MM-DD hh:nn:ss',now);
Now this will change the default view of the date to YYYY-MM-DD .... If you still want your view of the table to show MM/DD/YYYY... then you'll either need to go back to my prior comment about processing the string on the fly in the comparison for sort, or write a little view formatting code so that it displays in a format that's different than what is stored internally, which is a common view/model separation technique.
If you can write your original ALARMTIME format as MM/DD/YYYY and make sure you pre-pad with zeroes (e.g., 01/09/2018 not 1/9/2018) then you can use SQLite's substr function:
SELECT * FROM Alarms
ORDER BY (substr(ALARMTIME,7,4)||substr(ALARMTIME,1,2)||substr(ALARMTIME,4,2)||substr(ALARMTIME,11)) DESC
And you would create your ALARMTIME using this:
FieldByName('AlarmTime').AsString := FormatDateTime('dd-mm-yyyy hh:nn:ss', now);
The above solutions are fairly generic. Depending upon the client library you are using (which you have not specified), there may be another more suitable approach to solving the problem.
You cannot do, for example, SELECT * FROM Alarms ORDER BY ALARMTIME DESC and get an accurate sort since, for example, the date 12/1/2018 would come after 2/1/2018 in that sort ordering even though 2/1/2018 is later in time. This is because 2 follows 1 in the ASCII collating sequence.
If you need to keep your current ALARMTIME string format and not change how you're saving it, which is somewhat free form m/d/yyyy in which the day or month can have one or two digits, you're going to have a bit of work to do in order to sort it if your client library doesn't support some helpers in this regard. Perhaps your only other option would be to use a custom SQLite function. These are written in C and compiled and linked with SQLite. You'd have to find one already written, or write your own.

Core Data search where dates are saved as NSStrings

I am working on creating a search mechanism where the user can specify which fields to search on, the operators to use and the values to search for. More like an advanced search. However, I also need to search for dates and date ranges but the problem is that dates are declared as NSStrings and not NSDates. So basically they are strings that represent dates (and not literally dates as I am referring to them as). An example of a string that represents a date in the database is: 2014-11-25T00:00:00+1000.
So, without changing the values and their respective fields to NSDates in a migration, is there a way to keep what we already have but instead specify a sort of conversion criteria for my predicate query so that Core Data can convert the NSString field values to NSDates and then do the comparison to determine weather a record fits into the specified criteria or not?
I'm fairly sure that CoreData can't convert NSStrings into NSDates for you, what you'll have to do is create a parsing algorithm that converts it for you. The format looks like it's an ISO8601 date format, which is used in web development, so I'm assuming you've downloaded this data from somewhere?
I've developed date parsing algorithms before and with proper testing you can build something quite robust, quite quickly. What you can do then is convert your NSDate's into strings and then feed those strings into your fetch predicates.

How would I use an sql query with .where to check for a match between a date column and a string?

I have a hunch that this is sort of a hack already, but I was curious about this nonetheless:
Say I have this:
current_user.memories.where("content LIKE '%#{search}%' OR note LIKE '%#{search}%' OR date LIKE '%#{search}%'")
This is for a search field.
In my database, in the 'memories' table, I have content:text and note:string, so up through the first two compares, this trick works fine.
However, the date part doesn't work, obviously. I have a date:date column in the memories table too, but I don't know how to check for a match with the string.
I am fine with formatting the string to something like 2013-01-15, but I don't know how to do this comparison. Somehow change the 'date' part into that string too?
The idea behind this whole thing is to allow a search like 2013-01-15 (or some format) which would automatically check for dates too for 'memory' objects.
Advice appreciated.
(The db is postgres if that matters.)
First of all, you shouldn't be using string interpolation to build SQL, let ActiveRecord take care of that stuff. Secondly, if your search is in ISO 8601 format (i.e. YYYY-MM-DD) then you could directly compare the date column with the string use = and PostgreSQL will figure it out. You want something more like this:
current_user.memories.where(%q{
content like :pat
or note like :pat
or date = :date
}, :pat => "%#{search}%", :date => search)
You could convert your search term into a date by using to_date(text, text). You may also have to remove the time component from your date field if necessary
An explanation is here

Apache Lucene - search by concrete date

I want to find some data of a application which allows using Apache Lucene syntax for search queries. I search data by date and want to find data from concrete date - concrete day. How can I do that?
Queries:
date: [2010-10-4 TO 2010-10-4]
or
date: 2010-10-4
does not work.
Short answer: there is no "standard" for date query syntax in Lucene. You need to find out the format(s) your app supports.
Long answer: For the last couple years or so, Lucene keeps the numeric data specially encoded. Most likely, the date in the index is kept in the timestamp format. This means the query parser needs to take in the query, chew it and spit out the timestamp. Querying against a raw timestamp is not very practical - at least for humans - and your query parser likely has some pre-defined format it is able to understand.
For example, Solr has a pre-defined set of supported date/time formats and is able to parse those into timestamps.
Don't forget Lucene is just a library and each application (including Solr and the one you are using) is meant to use it the way they like.
I found the solution.
For searching by one conrete day, query:
date: [2010-10-4T00:00:00 TO 2010-10-4T23:59:59]
is correct
I put the date range without the hyphens and It worked for me.
date: [20210901 TO 20211101 ]
See the doc Range Searches

Lucene.net 2.9.4 SimpleFacetedSearch with numeric range on NumericField

I put some fields like manufacturer, group, description, num.
SimpleFaceted works ok if I use query like sometext* with QueryParser.
Im trying to use num:[100 TO 200],
num is NumericField with SetIntValue(150).
I got nothing returned.
Am I missing something?
You can't use a normal query parser for numeric range queries. However, assuming you know at query time which fields are numeric, it isn't too hard to derive a class from the Lucene query parser and create numeric range queries as necessary.
Support for numeric queries in the standard query parser looks like it should be available in Lucene.Net when a port of v3.4 is available. (See Java Lucene issue 1768)
Good luck,