Algolia AND search through an array
Asked Answered
C

1

6

I am looking for a way to search in Algolia a record where at least one element of an array meets several conditions. As an example, imagine this kind of record:

{
    "name": "Shoes",
    "price": 100,
    "prices": [
    {
        "start": 20160101,
        "end": 20160131,
        "price": 50,
    },
    {
        "start": 20160201,
        "end": 20160229,
        "price": 80,
    }
    ]
}

I am looking for a way to do a query like the following:

prices.price<60 AND prices.start<=20160210 AND prices.end>=20160210

(A product where the price is less than 60 for the given date)

That query should not return anything because the price condition is not met for that date but the record is returned anyway. Probably because the condition is met "globally" among all prices.

I am a beginner with Algolia and trying to learn. Is there a way I can do the desired request or will I have to go for a separate index for prices and use multiple queries?

Thanks.

Cohbath answered 8/1, 2016 at 17:7 Comment(0)
P
5

When a facetFilter or tagFilter is applied on an array, Algolia's engine checks if any element of the array matches and then goes to the next condition.

The reason it behaves that way and not the way you expected is simple: let's assume you have an array of strings (like tags):

{ tags: ['public', 'cheap', 'funny', 'useless'] }

When a user wants to find a record that is "useless" and "funny", this user is not looking for a tag that is both "useless" and "funny" at the same time, but for a record containing both tags in the array.

The solution for this is to denormalize your object in some way: transforming a record with an array of objects to multiple records with one object each.

So you would transform

{
    "name": "Shoes",
    "price": 100,
    "prices": [
      { "start": 20160101, "end": 20160131, "price": 50 },
      { "start": 20160201, "end": 20160229, "price": 80 }
    ]
}

into

[
  {
    "name": "Shoes",
    "default_price": 100,
    "price": { "start": 20160101, "end": 20160131, "price": 50 }
  },
  {
    "name": "Shoes",
    "default_price": 100,
    "price": { "start": 20160201, "end": 20160229, "price": 80 }
  }
]

You could either do this in the same index (and use distinct to de-duplicate), or have one index per month or day. It really depends on your use-case, which makes it a bit hard to give you the right solution.

Pandurate answered 9/1, 2016 at 13:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.