Is it possible to configure filters that use boolean logic for SearchProvider?

Hi there,

I'm currently using App Search with search-ui react library.

I'm looking for a way to apply boolean logic to the filters inside my searchQuery config.

Let's say I have 10 documents in my search engine.

Each document represents a coffee shop that has 2 fields: "shop_name" and "shop_country"

For those 10 documents: there are 5 coffee shops in the US, 3 shops in Canada, and 2 shops in Europe.

What would be the best way to query for coffee shops in North America (US + Canada)?

Let's say I'm passing this config prop into SearchProvider:

    const config = {
        searchQuery: {
            facets: buildFacetConfigFromConfig(),
            disjunctiveFacets: [],
            filters: [{ field: 'shop_country', values: ['US'] }],
        },
        apiConnect: newAppSearchAPIConnector({...}),
    }

   <SearchProvider config={config}>...</SearchProvider>

Is there a way to apply an "OR" condition to filters?

Or would I have to add shop_country as a facet, and make it disjunctive? But then how can I filter for 2 values?

Or would I have to change the schema and add a new field like 'north_america': 'true' ? and query for that specific field?

Thanks for the help in advance!!

Sure is!

filters: [
      {
        field: "shop_country",
        type: "any",
        values: ["US", "Canada"]
      }
    ],

They key here is to use type: "any".

The type definitions for this stuff can be found here.

We should make this more apparent in our documentation.

1 Like

That works, thanks Jason!!

I appreciate the type definitions link :pray:

Sorry Jason, I have one more related question:

Is it possible to apply an "OR" condition BETWEEN filters?

Let's say I have an additional field called "shop_shipping", because some US shops offer shipping to Canada.

If I try:

filters: [
      {
        field: "shop_country",
        type: "any",
        values: ["US", "Canada"]
      },

     {
       field: "shop_shipping",
       values: ["Canada"]
     }
    ],

If I add another filter object to the filters array, it narrows down the search, which is fine if I have documents that include 'Canada' in both shop_country and shop_shipping. But then I'm not sure how I could include European shops that ship to both US and Canada or just the US.

Basically, I'm trying to figure out the right schema and filters for these conditions:

"I'm in the US, which US or Canadian or European shops can SHIP to the US?"

"I'm in Canada, which US or Canadian or European shops can SHIP to Canada?"

"I'm in Europe, which shops can SHIP to Europe?"

I don't think I understand... this doesn't work?

"I'm in the US, which US or Canadian or European shops can SHIP to the US?"

filters: [
      {
        field: "shop_country",
        values: ["US"]
      },

     {
       field: "shop_shipping",
        type: "any",
       values: ["Canada", "US", "Europe"]
     }
    ],

"I'm in Canada, which US or Canadian or European shops can SHIP to Canada?"

filters: [
      {
        field: "shop_country",
        values: ["Canada"]
      },

     {
       field: "shop_shipping",
        type: "any",
       values: ["Canada", "US", "Europe"]
     }
    ],

"I'm in Europe, which shops can SHIP to Europe?"

filters: [
      {
        field: "shop_country",
        values: ["Europe"]
      },

     {
       field: "shop_shipping",
        type: "any",
       values: ["Europe"]
     }
    ],
1 Like

Thanks for your help Jason!! Sorry, I should be more clear

"I'm in the US, which US or Canadian or European shops can SHIP to the US?"

filters: [
      {
        field: "shop_country",
        values: ["US"]
      },

     {
       field: "shop_shipping",
        type: "any",
       values: ["Canada", "US", "Europe"]
     }
    ],

Wouldn't the config above would return all shops headquartered in US that can ship to either US or Europe or Canada?

Instead, I'm trying to return all shops headquartered ANYWHERE that can ship to the US. So this would make more sense:

filters: [
      {
        field: "shop_country",
        type: 'any'
        values: ["US", "Canada", "Europe"]
      },

     {
       field: "shop_shipping",
       values: ["US"]
     }
    ],

But what I can't figure out is how to arrange the schema because technically shop_shipping could be an array:

{
   shop_name: 'Coffee Shop based in America that can also ship to Canada but not Europe',
   shop_country: 'US',
   shop_shipping: ['US', 'Canada']
}

Would it be better to create a new fields like this?

{
    shop_name: 'Coffee shop based in Canada that ships to North America',
    shop_country: 'Canada',
    ships_to_US: true,
    ships_to_Canada: true,
    ships_to_Europe: false,
}

Then write queries like this perhaps?

   const [country, setCountry] = useState('US')

   filters: [
    {
        [`ships_to_${country}`]: true
    },

   ]

Thanks for your help again! I'm trying to brainstorm the best way to do this based on what I can do with config queries

Have you tried this out yet? I'm pretty sure this will just work.

This:

     {
       field: "shop_shipping",
       values: ["US"]
     }

Will match on this:

{
   shop_name: 'Coffee Shop based in America that can also ship to Canada but not Europe',
   shop_country: 'US',
   shop_shipping: ['US', 'Canada']
}
1 Like

Wow it works!! Thanks Jason!! I thought App Search only accepted strings, booleans, numbers and geolocations :thinking:

I'll be indexing docs with a shipping array from now on.

But in my current situation, I have thousands of docs like this with missing shipping data:

{
   shop_name: 'American based shop with missing shipping data',
   shop_country: 'US',
}

Right now, the config below excludes all of those docs:

     {
       field: "shop_shipping",
       values: ["US"]
     }

Is it possible to write a config that will match BOTH these docs below using a 'US' value?

{
   shop_name: 'American shop with missing shipping data',
   shop_country: 'US',
}

{
   shop_name: 'American shop with clean shipping data',
   shop_country: 'US',
   shop_shipping: ['US', 'Canada']
}

Because something like this:

     {
       field: "shop_shipping",
       values: ["US"]
     },
     {
       field: "shop_country",
       values: ["US"]
     }

would only return docs with shipping data:

{
   shop_name: 'American shop with clean shipping data',
   shop_country: 'US',
   shop_shipping: ['US', 'Canada']
}

Thanks for your help Jason! I appreciate it! :pray:

I don't think you can write a filter that matches on 'US' OR nothing. I think you'd have to actually have to index a value that represents, like 'None' or something.

So 'US' or 'None'. I don't know though, you might have to play around a little bit with the API and see what works!

1 Like

Ahh that's unfortunate but not a big deal! I'll just re-index the old docs.

Thanks for taking your time to help me!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.