Note this is a developer-experience (DX) issue; and was observed while working on Elasticsearch Connector's #3551591: Filter does not work with date range fields issue.

Problem/Motivation

Drupal core 8.2.0 introduced a Datetime Range module.

The Datetime Range module stores the start of the range in a property named value (like most other fields - this is also its main property name). Notably, though, it stores the end of the range in a property named end_value.

In Search API, the \Drupal\search_api\Utility\FieldsHelper class is responsible for extracting field values from entities so that they can be indexed.

When the FieldsHelper::extractFieldValues() function runs on a \Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem (i.e.: where $data instanceof DateRangeItem), it follows the "Process complex data types" branch in the code, which only extracts the main property name (value), and ignores the other property (i.e.: end_value).

The extracted data (which is now just a single date, the start date) is then passed to the Search API Data type plugin, in \Drupal\search_api\Item\Field::addValue().

If a module wants to add its own Search API Data Type plugin to handle date ranges (for example, Elasticsearch Connector's DateRangeDataType plugin, which is supposed to add support for Elasticsearch's date_range variant of its range field type), then the end_value data is no longer available by the time the Data Type plugin runs, and there's no reference back to the original entity (i.e.: to extract the end_value manually).

I can imagine this being an issue for other complex field types where there are multiple property values of equal importance. For example, Address, Double Field, etc.

***

I can see why it makes sense to return the mainPropertyValue for a complex data type; but if there is also no way for a Search API Data Type plugin to get the original field value, then site builders and/or module developers have to resort to more-complex work-arounds (e.g.: I think the developers of search_api_opensearch had to write a preprocessor plugin to support date range fields).

Steps to reproduce

  1. Download the latest version of Drupal core (I got 11.3.6) and search_api (I cloned 8.x-1.x branch and got commit e96a1c88)
  2. Install Drupal with the minimal install profile.
  3. Log in as an administrator
  4. Go to /admin/modules, enable field_ui, datetime_range, search_api, and search_api_db (other search backends will work too; I first noticed this issue with elasticsearch_connector).
  5. Go to /admin/structure/types/add and create a content type. I happened to give mine the machine name event.
  6. Go to /admin/structure/types/manage/event/fields/add-field, click Date and time. In the popup, enter Label = Event date (machine name field_event_date), Choose a field type = Date range, click the Continue button, then click the Save button to accept the defaults on the second page.
  7. Go to /node/add/event, set Title = Sprints, Start date = 2026-04-10 09:45:00, End date = 2026-04-11 16:15:00, then click the Save button.
  8. Go to /admin/config/search/search-api/add-server and add a Search API Server. I happened to give mine the machine name example_db_backend.
  9. Go to /admin/config/search/search-api/add-index, set Index name = Events, Datasources = Content, Server = example_db_backend, then click the Save button.
  10. Go to /admin/config/search/search-api/index/events/fields/add/nojs; and click the Add button next to the Event date (field_event_date) field. Then click the Done button. On the Manage fields for search index Events, in the field_event_date row, set Type = Date (doesn't really matter what you pick here since FieldsHelper discards the end_value before the field type is used). Click the Save changes button.
  11. If possible, set breakpoints in the following functions...
    1. \Drupal\search_api\Utility\FieldsHelper::extractFieldValues()
    2. \Drupal\search_api\Item\Field::addValue()
    3. \Drupal\search_api\Plugin\search_api\data_type\DateDataType::getValue()


    ...Then, go to /admin/config/search/search-api/index/events and click the Index now button.

  12. Observe...
    1. First, you hit the breakpoint in \Drupal\search_api\Utility\FieldsHelper::extractFieldValues(), stepping through note the end_value is discarded
    2. Next, you hit \Drupal\search_api\Item\Field::addValue(), and the value passed in is just the value of the start_date
    3. Finally, you hit the breakpoint in \Drupal\search_api\Plugin\search_api\data_type\DateDataType::getValue(), and at this level of the code, there is no longer any way to find the end_value or even the original DateRangeItem to extract the end_value from that

Proposed resolution

Not exactly sure, but if there was a way to pass a reference to the original DateRangeItem, that would be helpful!

Remaining tasks

  1. Decide on a solution
  2. Write a merge request with tests
  3. Community review
  4. Maintainer review
  5. Commit
  6. Release

Comments

mparker17 created an issue. See original summary.

mparker17’s picture

Not sure if this will be helpful, but I took a screenshot of the call stack and defined variables in \Drupal\search_api\Utility\FieldsHelper::extractFieldValues(), and annotated it a bit. I've attached it here.

mparker17’s picture

Issue summary: View changes

(fixed a few typos in the issue summary)

joachim’s picture

The end_value works ok for me in a search index if I add it to the index as a separate property.

joachim’s picture

It's the *start value* that's broken for me -- see #3591122: date_range field is not treated as a date in Search index .