algolia / firestore-algolia-search

Apache License 2.0
112 stars 35 forks source link

Filtering collection #57

Closed Bones5 closed 3 years ago

Bones5 commented 3 years ago

I only want to index records that are published. I have a boolean isPublished and I would only like records from my collection that are published to be indexed.

I've tried using the transform function but I get an invalid JSON error if I try to return anything other than the data.

Does the extension allow me to filter records before they are sent to Algolia?

Haroenv commented 3 years ago

What do you return from the transform function? This plugin reads .result of the response of the function. If you don't want to keep any, if I understand it correctly that response should be { result: [] }

https://github.com/algolia/firestore-algolia-search/blob/f29a83e6faf7b9fb6632e0558c314e3f8a4f395b/functions/src/transform.ts#L25-L31

Bones5 commented 3 years ago

Thank you, I see my error now.

I thought the function operated on each record individually rather than receiving an array of all the records.

That makes a lot more sense.

Haroenv commented 3 years ago

I'll close this issue now, but if you have further questions, feel free to ask!

Bones5 commented 3 years ago

OK, so having looked at this further it appears the transform function is applied to each individual record as described in the ReadMe.

(My biggest problem was actually that my function was in Europe-West-1 not Europe-West-2 and that returned the JSON error. Whoops.)

What I want to do is this:

import * as functions from "firebase-functions";

const searchIndexing = functions
  .region("europe-west2")
  .https.onCall((record: any, context) => {
    if (record.isPublished) {
      return record;
    } else {

      // Do not index this record or remove if it is already present

      return;
    }
  });

Having looked at the extension it looks like this is not possible at the moment as the transform function is applied after the decision to Create or Delete from Algolia.

Is there a better way to do this or should this be a feature request?

Haroenv commented 3 years ago

Sorry for explaining wrong, I think it makes sense as a feature request!

smomin commented 3 years ago

Hello @Bones5

Algolia Search configuration provides a way to filter your search results by using filtering or Query rules. I would recommend this approach. I am hesitant to add code for this use case. Also, I would also suggest not sending attributes in the search results that might not be relevant in the search experience, https://www.algolia.com/doc/api-reference/api-parameters/unretrievableAttributes/.

Let me know if you have any questions.

Sajid

Bones5 commented 3 years ago

Thanks for your reply @smomin

It does look like this is typically done in Algolia. It is similar to an "inStock" for something like Shopify.

Looking at this example it is applied in at during the index https://www.algolia.com/doc/api-reference/api-parameters/numericFilters/#examples

I'm a bit confused how to replicate this using the plugin, do you know where I would add this search to the index?

Haroenv commented 3 years ago

If you have the "in stock" attribute as a key of the object/record, you can set it as attributesForFaceting and use filters frontend to hide or display those: facetFilters: [['inStock:true']] for example. You can also use InstantSearch' toggleRefinement or refinementList for making the UI

Bones5 commented 3 years ago

Thanks for your help @Haroenv

I got there in the end. I spent a lot of time trying to apply the API configuration when it was the was the Configure component I really needed.

<Configure facetFilters={[["isPublished:true"]]} /> 👍