On our site, we have a date field that has a monthly granularity, so that the field has values like 10/2013, 11/2013, etc.

When using Facet API, drilling down to October for example displays results from midnight on October 1 to midnight on November 1, thus showing results from both October and November.

To fix this, we must not include the right-hand endpoint in the date interval filter. The attached patch subtracts one second from each granularity (except for granularity by second). If the granularity is by second, the interval is 0 seconds instead of 1 second as it stands now.

I should note that the exact place where this is causing problems is in Search API's Facet API plugin in the file query_type_date.inc, specifically this chunk of code which makes use of Facet API's facetapi_get_next_date_increment function:

185     // Treat each date as the range start and next date as the range end.
186     $range_end = array();
187     $previous = NULL;
188     foreach (array_unique($dates) as $date) {
189       if (NULL !== $previous) {
190         $range_end[$previous] = facetapi_get_next_date_increment($previous, $gap);
191       }
192       $previous = $date;
193     }
194     $range_end[$previous] = facetapi_get_next_date_increment($previous, $gap);

If this bug needs to be fixed in Search API's implementation of this function then feel free to change the project.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

caesius’s picture

Title: Use left-open, right-closed intervals for date ranges ("gaps") » Use left-closed, right-open intervals for date ranges ("gaps")
caesius’s picture

Assigned: Unassigned » caesius
Status: Active » Needs review
caesius’s picture

Previous patch had a bug due to facetapi_get_timestamp_gap expecting old input. Updating.

caesius’s picture

Issue summary: View changes
caesius’s picture

Forgot a break in the switch statement.

cpliakas’s picture

Status: Needs review » Needs work

Thanks for the contribution!

Marking as needs work, because this is a really hard problem to solve in Facet API. Solr has certain ways of handling dates as does database searches and other backends. Therefore a fix on the Facet API layer can fix the issue on on backend but break another.

In order to move this forward we need to have a small test dataset that shows the bug on multiple backends, for example Apache Solr Search, core search, and Search API with either database search or it's Solr integration. We need to be sure whatever fix is applied works across the board.

Thanks,
Chris

maxocub’s picture

I don't know which search backend you are using, but if you are using Apache Solr, this kind of queries are already supported:

  • [2018-11-01T00:00:00Z TO 2018-12-01T05:00:00Z]
    (From November 1st to December 1st, including both start and end dates)
  • {2018-11-01T00:00:00Z TO 2018-12-01T05:00:00Z}
    (From November 1st to December 1st, excluding both start and end dates)
  • [2018-11-01T00:00:00Z TO 2018-12-01T05:00:00Z}
    (From November 1st to December 1st, including the start date but excluding the end date)
  • {2018-11-01T00:00:00Z TO 2018-12-01T05:00:00Z]
    (From November 1st to December 1st, excluding the start date but including the end date)

I don't know how other search backends deal with those kind of queries, but I did make it work with Solr by changing the FACETAPI_REGEX_DATE_RANGE constant.
I'm including a patch in case it helps someone else.
The patch won't break other backends (I think) but it may not fix the problem for those backends.

If this patch is not useful here, please let me know and I'll open another issue.

maxocub’s picture

FileSize
549 bytes

Removing noise from the previous patch.