One field free text query on Elasticsearch supporting dates

I originally asked this question on StackOverflow, but haven't found a satisfactory answer yet:

Suppose I have an index with multiple fields of type text and one or more of type date (of some format, say yyyy/MM/dd ). If I want to enable users to perform queries using only a single input field (so, Google-like), how should I go about supporting the date fields? The text fields, so far, are mainly queried using the simple_query_string and multi_match queries.

Now, the simple_query_string works fine as long as an entire date in the correct format is searched. But if, for instance, I want to filter by year, the missing fields are automatically filled with the smallest accepted value (so e.g. for months it's 01).

Here's the approaches I've tried so far:

  • split the components of a date field into year, month etc. This however, as far as I can make out, requires an update_by_query , while having this rule at index time would be much nicer...
  • use range query. The available formatting however does not support the level of freedom the user input should have (so something like 2000 <some-name> would not be accepted...
  • copy the value as date to a different field and accept more formats -> doesn't work like that...

What my next approaches could be:

  • define an analyzer that splits dates by available delimiters and index everything as text and query as text. This should probably work, but elegant it is not...
  • change the logstash pipeline to write the date components to different fields. However, it feels like this should be possible to do in Elasticsearch itself...

Anyone had to solve this specific problem before? Thanks for suggestions!


What works is doing the update_by_query to extract the desired fields, like so

POST date_test/_update_by_query 
  "script": {
    "source": """
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
      LocalDate ldt = LocalDate.parse(ctx._source.GEBURTSDATUM, formatter);
      ctx._source.GEBURTSJAHR = ldt.getYear();
      ctx._source.GEBURTSMONAT = ldt.getMonthValue();
      ctx._source.GEBURTSTAG = ldt.getDayOfMonth();

Could this be translated into an index mapping instead of using the update api?

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.