Search with filter: "attribute < int or facet:-value"

I have a site search that contains Events and then other types of content such as Pages and Articles.

If I want to search across all content but filter out any events whose start date has passed how can I accomplish this?

I can do

instantsearch.widgets.configure({
    hitsPerPage: 10,
    filters: `event_start_date_filter_timestamp > ${yesterday}`,
}),

OR

instantsearch.widgets.configure({
    hitsPerPage: 10,
    facetFilters: ["post_type_label:-Events"]
}),

But not

instantsearch.widgets.configure({
    hitsPerPage: 10,
    filters: `event_start_date_filter_timestamp > ${yesterday} OR post_type_label:-Events`
}),

items with a start date greater than yesterday or not an event.

Basically, I want to filter out events that are no longer relevant for this search without removing items that do not contain that field.

Hi @support_discovernepa

First I think it important to look at your date format. As per What Is in a Record | Dates

If you want to filter or sort by date, then you should format date attributes as Unix timestamps

So if your dates are not currently like this, you need to convert them (though given your filter key has timestamp on it, you may already have done so.)

The Filter By Date documentation has several examples.

If you wish to exclude past events (from reading your post this is what I believe you wish to do) then you would filter event that are >= today (or yesterday.) See this example from the filter by date docs

const nowTimestamp = Date.now();

index.search('query', {
  filters: `date_timestamp >= ${nowTimestamp}`
}).then(({ hits }) => {
  console.log(hits);
});

I may have not been clear.

I have multiple types of content, lets say Events and Articles. One of my content types, Events, has a start_date field on it. the Event’s start_date is a timestamp. Article does not have a start_date value.

I want a search that can search both Events and Articles by keyword but I want to exclude and Events that are in the past from the results. How can I write a filter that excludes some records by a field when other records don’t have that field?

I essentially am trying to get a filter that does the following: event_start_date_filter_timestamp > ${yesterday} || post_type:-Events

So I think what you want is (pseudocode)

post_type IS 'Aricle' OR (
  post_type IS 'Event' AND event_start_date_filter_timestamp > ${yesterday}
)

which according to these usage notes is not a supported filter.

That’s right, you can’t mix between different types of filters disjunctively as it would create a too complex to parse filter, which would slow down the search.

Given my use case, how would I work around this? what is the proper way to approach this problem?

I need all content excluding events that are past

potential workaround: index a fake timestamp in the event_start_date_filter_timestamp field way in the future on non-event content so that those will never be “past”

maybe the real fix: some sort of custom cronjob that runs daily to remove events that are past from the index

Hi @support_discovernepa You could use just one of the filters on your search query and then iterate through the results and filter out the others in your code, but I think your cronjob to remove events may be your best bet.

Another option is to do multi-index search, you could search twice in the same index, once only for articles, once for posts that aren’t outdated. That way you’ll get two sets of results you could show side-by-side or subsequently, without changing your index

the downside of this is that we end up with a non-standard # of items per page if we remove items on the results at display time

in this particular instance we want the results intermixed and sorted by relevancy

1 Like