2

I have an index on algolia having users like this

UserA:

{
 createdAt: 1675364400000,
 email: "abc@gmail.com",
 products: [
   {
    productId: 'product1',
    dateAdded: 1675364400000,
    dateUpdated: 1675364400000,
    status: 'active'
   },
   {
    productId: 'product2',
    dateAdded: 1675364400000,
    dateUpdated: 1675364400000,
    status: 'pending'
   },
 ]
}

UserB:

{
 createdAt: 1675364400000,
 email: "abc1@gmail.com",
 products: [
   {
    productId: 'product4',
    dateAdded: 1675364400000,
    dateUpdated: 1675364400000,
    status: 'active'
   },
   {
    productId: 'product5',
    dateAdded: 1675364400000,
    dateUpdated: 1675364400000,
    status: 'pending'
   },
 ]
}

Need to apply filter on algolia to get all the users who has product2 with pending status. I'm getting both UserA (because it has product2 pending) and UserB (because it has product with pending status).

I added products.status and products.productId in attributesForFaceting and used the following in filters products.productId:product2 AND products.status:pending. Its getting all the users having product2 and any products with status pending

Ghayoor ul Haq
  • 670
  • 6
  • 24
  • Is this even possible using this structure? Found this on a forum and seems like a need to change the structure of array? https://discourse.algolia.com/t/filtering-with-a-property-that-is-an-array-of-objects/4693 – Ghayoor ul Haq Feb 02 '23 at 14:45
  • the example you have given will not cause the problem since `products.productId:product2 AND products.status:pending` is only in user A. but you will get it wrong if the products array had something like `[{productId: 'product2',status: 'active'},{productId: 'product4',status: 'pending'}]` – cmgchess Feb 03 '23 at 15:36
  • in that case you will have to do something like in the forum. also something similar https://stackoverflow.com/questions/74381551/how-to-query-algolia-data-with-in-the-array-of-object/74535013#74535013 – cmgchess Feb 03 '23 at 15:38
  • 1
    Thanks @cmgchess for your comments, I've checked this and it seems there will be a lot of redundant data if we do something like that, to avoid this I've implemented something else, and I'll post the answer soon, I'll appreciate it if you'll give a thought on that. – Ghayoor ul Haq Feb 03 '23 at 16:09
  • Great. i'm curious to know your workaround. Did you combine the 2 fields to 1 – cmgchess Feb 04 '23 at 03:23

1 Answers1

1

Changing the structure of the index on algolia helped me to resolve this issue. There are multiple ways to structure the index like mentioned in this but with this approach, can have redundant data and more requests to algolia if we need to update the other fields like createdAt in my case. Here is the structure I used to avoid all these overheads.

{
 createdAt: 1675364400000,
 email: "abc@gmail.com",
 "product1": {
    productId: 'product1',
    dateAdded: 1675364400000,
    dateUpdated: 1675364400000,
    status: 'active'
  },
 "product2": {
    productId: 'product2',
    dateAdded: 1675364400000,
    dateUpdated: 1675364400000,
    status: 'pending'
  }
}

And in attributesForFaceting added product1.status, product2.status, and the same for all our products. In this way, if we need to update the createdAt on algolia, we must change just one object with no redundant data.

We have a limited number of products that will not change very often. This might have some issues with attributesForFaceting if we have many products and change very often.

I would love to hear suggestions for improvement.

Ghayoor ul Haq
  • 670
  • 6
  • 24
  • This looks good considering there is a fixed number of products – cmgchess Feb 05 '23 at 10:06
  • Another workaround that came to my mind was to combine the two fields. Something like `"status":"product1-active"`. But I'm not sure how clean this solution is considering you will have to change the status field to have product name during indexing and also you might have to restructure the search result so that status has only the value active – cmgchess Feb 05 '23 at 10:19