Negating many id's from search

Hi

I’m constructing a query string on search ( react-instantsearch ) to filter out some IDs from the results. The string will look like below:

filters: "id != 7092 AND id != 669 AND id != 6879 AND id != 6845 AND id != 124 AND id != 290"

This string could get really long and just wondered if this would always be performant? The docs don’t list a NOT IN operator which leads me to believe it’s not the best way to do this?

Thanks for any help
Joe

Hi,

Unfortunately, there is no NOT IN (...) filter available in Algolia, and having a very long list of filters will impact performances negatively.

However, depending on your use case, there probably is another way to achieve what you are trying to do.
Would you mind sharing what your end goal is, with that filter?

Best,
Jonathan

Hi Jonathan

Thanks for your reply.

Each search item will have a list of ids ( other search items ) that they have matched against and consequently hidden by our users. These IDs don’t need to be shown in any subsequent query but will be different for every item in the index.

I’ve tried filtering the results however it messes up the results page. For example, page 2 might contain 10 IDs that are hidden, meaning no results are shown.

Does that help at all?

Joe

Hi,

Thanks for the description of your use case, it made a few things clearer.
I may have an acceptable solution, which is to take the inverse approach to your problem:

Instead of having a list of ids to filter out in each items, you could have each item hold the list of items they should not appear for. Then when you are doing your query, you apply a single negative filter (basically NOT id:${currentObjectID})

I believe this would allow you to do what you are trying to achieve in a more efficient way, so let me know if this helps you solve your issue!

Jonathan

Hi Jonathan

Really appreciate your response. Just trying to get my head around it, so on the items I would have for example a property ‘matched’ with a list of ids.

matched:{ 256, 12, 233, 44, ...etc }

Then the current search would have the filter:

NOT matched:${12}

Would this work against that property, with it being an object itself?

Apologies If I’m not understanding what you have suggested and thanks for your time.

Thanks

Joe

Hi Joe,

Yes, filters work against arrays of values, and the negation in this case means “not present”. But it’s true that an example would have made things clearer, so I’ll try to explain with an example this time.

If I understand you current solution would be something akin to this:

// record A
{
  name: 'A',
  objectID: 123,
  ignore: [234,345,...]
}
// record B
{
  name: 'B',
  objectID: 234,
  ignore: [345,...]
}
// record C
{
  name: 'C',
  objectID: 345,
  ignore: []
}

So that when you display record A, you don’t display record B in a “suggested” list because the record A says to ignore that id. In this model you would have to do the filter id != 234 && id != 345 && ....

However, if you transpose the ignore matrix into fields named ignoredBy, you would get the following model for your records:

// record A
{
  name: 'A',
  objectID: 123,
  ignoredBy: []
}
// record B
{
  name: 'B',
  objectID: 234,
  ignoredBy: [123]
}
// record C
{
  name: 'C',
  objectID: 345,
  ignoredBy: [123,234]
}

Then, if you want to search for results relevant to record B, applying the following filter will yield the expected results:

{
  "filters": "NOT ignoredBy:234"
}
// yields Record A and Record B

I hope this clarifies it a bit.