Elastic API custom date field range query - elasticsearch

I'm learning Elasticsearch API while practicing I'm facing the issue is unable to fetch documents between two dates those documents match two fields but without date range it's working fine
BoolQueryBuilder filter = new BoolQueryBuilder();
BoolQueryBuilder query = QueryBuilders.boolQuery();
for (String q : list) {
// both the fields must exists
query = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("field1", q))
.must(QueryBuilders.matchQuery("field2", val));
filter.should(query);
}
filter.must(QueryBuilders.rangeQuery("datetime").gte(from).lte(to);
searchSourceBuilder.query(filter);
Where,
list contains the list of words for the field1 field.
Both field1 & field2 must match such document I want to retrieve
datetime is a custom datetime field & the value looks like 2022-06-09 12:32:36
Can anyone help me to resolve this issue

I think you need, Date format to convert date values in the query. To format your dates, either use the built-in formats provided by ES - https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html
or, you can try customised format - https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
After formatting, gte and lte should work as expected.

Related

Lotus sorting view on orderdate does not work properly

I have created a view in which I also have a column which holds dates. This column can be sorted on ascending and descending. This is my column properties value:
But the problem is that the view does not sort the dates properly:
And here a screenshot of the orderdate field itself:
And here screenshot of the document with the orderdate that is out of order in the view:
Update
Some documents had the orderdate as text instead of date.. I create these documents through a java agent. The field orderdate I fill in like this:
SimpleDateFormat formatterDatumForField=new SimpleDateFormat("dd-MM-yyyy");
docOrder.replaceItemValue("Orderdatum",formatterDatumForField.format(currentDateForField));
But it is saved as text instead of date. Anyone knows why?
Problem was that orderdate field was set by a backend agent and this field was set with a string.
I know saved the current time as a DateTime object and now it works:
DateTime timenow = session.createDateTime("Today");
timenow.setNow();
docOrder.replaceItemValue("Orderdatum", timenow);
It's not clear to me why it's not working for you, but you can brute force it with something like this in the column formula
dateForSure := #TextToTime(OrderDatum);
#Text(#Year(dateForSure)) + "-" + #Text(#Month(dateForSure)) + "-" + #Text(#Day(dateForSure));
Also: your Java code saves a text value because the format() method of SimpleDateFormat returns a StringBuffer. The ReplaceItemValue method generates a text item when its input is a String or StringBuffer. Assuming your form defines OrderDatum as a Time/Date field, you can call Document.ComputeWithForm in your code to force it to convert the text item to a Time/Date. Another method - probably preferable given the potential side-effects of calling ComputeWithForm would be to create a DateTime object in your Java code and pass it to the ReplaceItemValue method instead.
It's because formatterDatumForField.format(currentDateForField) returns a String instead of a date/time value. Assuming that currentDateForField is a date/time value, you should change
SimpleDateFormat formatterDatumForField=new SimpleDateFormat("dd-MM-yyyy");
docOrder.replaceItemValue("Orderdatum",formatterDatumForField.format(currentDateForField));
to
docOrder.replaceItemValue("Orderdatum",currentDateForField);

Searching without duplication - aggregations and tophit

I am beginning with ElasticSearch and really like it, hovewer I am stuck with quite simple scenario.
I am indexing such structure of a Worker:
NAME SURENAME ID AGE SEX NAME_SURENAME BIRTH_DATE
NAME_SURENAME - not analyzed - this field is indexed for grouping purposes
NAME, SURENAME - analyzed
The task is simple - search 5 unique workers sorted by birth_date (unique means the same name and surename, even if they are in different age and are different people)
I read about aggregation queries and as I understand, I can get only aggregations without documents. Unfortunatelly I aggregate by name and surename so I won't have other fields in results in buckets, like for example document ID field at least. But I also read about TopHit aggregation, that it returns document, and i tried it - the second idea below.
I have two ideas
1) Not use aggregations, just search 5 workers, filter duplicates in java and again search workers and filter duplicates in Java till I reach 5 unique results
2) Use aggregations. I event tried it like below, it even works on test data but since it is my first time, please advice, whether it works accidentially or it is done correctly? So generally I thought I could get 5 buckets with one TopHit document. I have no idea how TopHit document is chosen but it seems to work. Below is the code
String searchString = "test";
BoolQueryBuilder query = boolQuery().minimumNumberShouldMatch(1).should(matchQuery("name", searchString).should(matchQuery("surename", searchString));
TermsBuilder terms = AggregationBuilders.terms("namesAgg").size(5);
terms.field("name_surename");
terms.order(Terms.Order.aggregation("birthAgg", false)).subAggregation(AggregationBuilders.max("birthAgg")
.field("birth_date")
.subAggregation(AggregationBuilders.topHits("topHit").setSize(1).addSort("birth_date", SortOrder.DESC));
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("workers")
.addAggregation(terms).setQuery(query).setSize(1).addSort(SortBuilders.fieldSort("birth_date")
.order(SortOrder.DESC));
Terms aggregations = searchRequestBuilder.execute().actionGet().getAggregations().get("namesAgg");
List<Worker> results = new ArrayList<>();
for (Terms.Bucket bucket : aggregations.getBuckets()) {
Optional<Aggregation> first = bucket.getAggregations().asList().stream().filter(aggregation -> aggregation instanceof TopHits).findFirst();
SearchHit searchHitFields = ((TopHits) first.get()).getHits().getHits()[0];
Transformer<SearchHit, Worker> transformer = transformers.get(Worker.class);
Worker transform = transformer.transform(searchHitFields);
results.add(transform);
}
return results;//

Retrieving documents in order they were inserted

I am wanting to know how to create an index in rethinkdb that will return rows in the order they were added, to use it as a kind of log.
You will want to set a datetime field of some sort in your documents like so:
# Shorthand for table
test = r.db("test").table("test")
# Create index
test.createIndex("datetime", r.row("datetime"))
# Insert document with datetime field
test.insert({
datetime: r.now(),
})
# To get all documents in sorted order
test.order_by(index="datetime")
# To get documents after a certain point
test.between(<some sort of datetime object>, r.maxval, index="datetime")
https://www.rethinkdb.com/api/python/order_by/
https://rethinkdb.com/api/python/between/

Sonata admin, use text filter for date filter

I'm using SonataAdminBundle and I have a question about filters.
When I have a text field in my entity, in my filter I can see 3 types of filters :
contains
not contains
is equal
When I have a date field in my entity, i can see these filters :
=
>=
<
...
How can I use text filters instead of date filters (or math filters) when I have a date field ?

how to sort the documents according to an field in lucene?

guys.
I've got billions of records which have two attributes:
RecordCreatedTime, RecordContent
I've used lucene to index the records, and it is done.
Now I want to query some records according to the RecordCreatedTime, for example, check out the document just in November, 2013.
I am considering to sort the documents with RecordCreatedTime, and have tried some methods like NumericDocValuesSorter but it didn't work.
Can you guys provide some more materials so I can take a careful look??
Much thanks.
You should check out Lucene's DateTools which provides you with the tools to represent dates in a way that is appropriate for searching and sorting in the index. A TermRangeQuery can be used to search a particular range (such as the month of November, 2013), when indexed in that format.
You can also sort easily, by passing a Sort into your search call.
For example, something like:
String startDateString = DateTools.dateToString(startDate, DateTools.Resolution.DAY);
String endDateString = DateTools.dateToString(endDate, DateTools.Resolution.DAY);
TermRangeQuery query = TermRangeQuery.newStringRange("recordCreatedTime", startDateString, endDateString, true, false);
SortField field = new SortField('recordCreatedTime', SortField.Type.STRING);
Sort sort = new Sort(field);
TopDocs results = searcher.search(query, numDocs, sort);

Resources