Numeric Search Inside array of objects

Hi,

I have my documents which is a list of jobs indexed in this way. They contain a key called timeslots which has a list of allowed working hours. So for ex, below json means user can work either from 9-15 or 10-16 and so on.

{
   "timeslots":[
      {
         "l":9,
         "u":15
      },
      {
         "l":10,
         "u":16
      },
      {
         "l":11,
         "u":17
      },
      {
         "l":12,
         "u":18
      },
      {
         "l":13,
         "u":19
      },
      {
         "l":14,
         "u":20
      }
   ]
}

Now I want to match the jobs as per user’s work preference. So for ex, if user wants to work between 10-18, the above job should match because it matches to 3 slots in above json (10-16, 11-17 and 12-18). However if he chooses to work between say 12-16, the job shouldn’t match.

I created my filter in this way. Basically any of the timeslot inside timeslots array should be such that the lower and upper of the slot falls between the lower and upper preference of the user.

numericFilter = [
   "timeslots.l >= user_lower",
   "timeslots.u <= user_upper"
]

However, this filter is working incorrectly because it matches lower to any of the l key in slots and u to any of the keys in slots. So this shows a match even for 12-16 because the 1st condition is satisfied by l:12,u:18 and 2nd condition is satisfied by l:10,u:16 which I don’t want.

My question is, how do I restrict my search in such a way that both l and u match should happen on the same slot object and only if there is atleast 1 matching object in array, this should return the object?

Hi there,

I’m Dorian, software engineer at Algolia.

Have you tried using an AND operator? Something like:

numericFilter = [
   "timeslots.l >= user_lower AND timeslots.u <= user_upper"
]

You can find more about it in our documentation

Let me know if this helps,

Cheers,

Thanks for your reply Dorian. Actually if you see my filter, its exactly same written in array format. The problem with the AND operator is that its not searching inside a single slot object. So the lower limit filter searches inside all the slots and the upper limit also does the same.

So for example, with lower as 12 and upper as 16, the above json should not match since there is no slot object which satisfies both the conditions. But algolia returns this object because it finds timeslots[3] >= 12 and finds timeslots[1] <= 16 and considers the condition satisfied even though both of them are different slots.

I see, I was hoping the AND would force the algorithm to select values from the same element. Since it’s not possible, the easiest alternative I can think of would be to populate your array objects with a duration key being equal to upper - lower and to filter on that. What do you think?

Didn’t get it. Can you please explain with an example? Even if I have a duration key, how do I match whether any of the working slots falls within the user’s preference?

So for example, if user marks his preference as 6-14, this job shouldn’t get selected because even though he has 8 hours availability while the job requires 6, he cannot match any 6 hour slot that the job requires. While a 7-15 will be a match since he can work the first slot of 9-15.

Hi @akash, one solution might be to create multiple records, one for each time slot, instead of including them all in an array on the same record. All other data on the record could be the same, but you could then use the ‘distinct’ parameter to group the records. Then you could use your ‘and’ filter to find the correct timeslot.

Hi Cindy, Thanks for the response. I thought of the same approach that you are suggesting but this would create lots of duplicate documents with just 1 key changed since there can be a lot of time slots. I thought maybe there could be a better approach to this.

Hello @akash,

Filters work at the record level, so you can’t filter the way you expect with all time slots in the same record. If you want to go with Algolia conjunctive filters, @cindy.cullen’s solution with the multiple records and distinct is the way to go.

If you can’t go this route, you will need to perform custom filtering, on your front end.