# Ruby, App Search, filters & my sanity

**URL:** <https://discuss.elastic.co/t/ruby-app-search-filters-my-sanity/266406>\
**Category:** Elastic Search\
**Tags:** elastic-app-search\
**Created:** [March 5, 2021, 7:06pm UTC](https://discuss.elastic.co/t/ruby-app-search-filters-my-sanity/266406 "2021-03-05T19:06:30Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![brianw123](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/brianw123/32/85068_2.png) [@brianw123](https://discuss.elastic.co/u/brianw123)\
**Post date:** [March 5, 2021, 7:06pm UTC](https://discuss.elastic.co/t/ruby-app-search-filters-my-sanity/266406/1 "2021-03-05T19:06:30Z")

</div>

Hello! I've been losing my mind trying to figure out how to use multiple filters on a query using the Ruby gem for App Search (elastic-enterprise-search).

Reading the docs here:

> **[App Search API | enterprise-search-ruby \[7.11\] | Elastic](https://www.elastic.co/guide/en/enterprise-search-clients/ruby/7.11/app-search-api.html)**

I'm not seeing any examples using multiple filters.

So let's head here:

> **[Search API filters | Elastic App Search Documentation \[8.4\] | Elastic](https://www.elastic.co/guide/en/app-search/current/filters.html#filters-combining-filters)**

Great! Now, I need to do is something like this (JSON):

```auto
"filters": {
  "all": [
    { "states": ["Washington", "Idaho"] },
    { "world_heritage_site": ["true"] }
  ]
}

```

And then convert it to Ruby:

```auto
filters: {
  all: [
    { state: ['Washington', 'Idaho'] },
    { world_heritage_site: ['true'] }
  ]
}

```

But I keep running into an error:  
**"Filters contains an invalid set of keys for object inside of field: all; can only have clauses or a single field name"**

I've tried other variations of the syntax as well:

```auto
filters: {
  all: {
    state: ['Washington', 'Idaho'],
    world_heritage_site: ['true']
  }
}

```

No dice. I can just remove either one of the OR's and it'll work:

```auto
filters: {
  all: {
    state: ['Washington', 'Idaho'],
  }
}

```

Or with the other syntax will also work:

```auto
filters: {
  all: [
    { world_heritage_site: ['true'] }
  ]
}

```

But I'll keep getting the above error if I add more than one OR.

I feel like I'm missing something super obvious here and any pointers would be greatly appreciated. Thank you!

---

<div class="post-metadata">

**Author:** ![constancecchen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/constancecchen/32/71762_2.png) [@constancecchen](https://discuss.elastic.co/u/constancecchen)\
**Post date:** [March 5, 2021, 7:32pm UTC](https://discuss.elastic.co/t/ruby-app-search-filters-my-sanity/266406/2 "2021-03-05T19:32:55Z")

</div>

Heya Brian, thanks for posting! I'm not a Ruby expert so I'm going to grab one of my coworkers who is, but let me see what I can help with in the meanwhile.

To quickly start - the 3rd example you gave should **definitely** not work / should absolutely trigger the error you're seeing. From your example, `all` either wants an array of objects with a **single** key, or it wants a single object with a single key. The below should definitely fail:

```auto
  all: {
    state: ['Washington', 'Idaho'],
    world_heritage_site: ['true']
  }

```

I'm testing against my local national parks sample engine and I'm a little puzzled. Just to make sure, are you definitely giving us the code you're actually running (presumably against a sample engine), or are you just giving us a dummy/example? If you're actually sending this search, then the main issue I see is that `state` should be `states`, and you should be getting a `Filters contains invalid key: state` error.

If it's just an example - would it be possible for you to give us the **exact** code/syntax you're sending? Again, it sounds like the issue is your `all` array potentially has an object with multiple keys in it instead of just a single key, but it's hard to say without the actual code.

---

<div class="post-metadata">

**Author:** ![brianw123](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/brianw123/32/85068_2.png) [@brianw123](https://discuss.elastic.co/u/brianw123)\
**Post date:** [March 5, 2021, 8:13pm UTC](https://discuss.elastic.co/t/ruby-app-search-filters-my-sanity/266406/3 "2021-03-05T20:13:47Z")

</div>

Hi Constance,  
You are correct in that this was all dummy code. You bring up a good point and I should try to create a full, focused example.

I loaded that [parks data](https://data.world/kevinnayar/us-national-parks) back in as a new engine to test against. My data is a little busted but I'm not worrying about results at this point, just the query going through.

Here's a failing example:

```auto
client = Elastic::EnterpriseSearch::AppSearch::Client.new(host: url, http_auth: auth_key)
client.search('parks', {
  query: "olympic",
  filters: {
    all: {
      states: ["Washington", "Idaho"],
      world_heritage_site: ["true"]
    }
  }
})

```

Like you said, the above does fail and `all` should be an array:

```auto
client.search('parks', {
  query: "olympic",
  filters: {
    all: [
      { states: ['Washington', 'Idaho'] },
      { world_heritage_site: ['true'] }
    ]
  }
})

```

This actually returns a Ruby error:  
`TypeError (no implicit conversion of String into Integer)`

Which makes me think the gem isn't ready for those arrays, because if I run this:

```auto
client.search('parks', {
  query: "olympic",
  filters: {
    all: [
      { states: "Washington" },
      { world_heritage_site: "true" }
    ]
  }
})

```

The query is run but I get the "Filters contains an invalid..." error again.

And as before, if I remove one of the filters it works:

```auto
client.search('parks', {
  query: "california",
  filters: {
    all: [
      { states: "Washington" },
    ]
  }
})

```

My gut says I'm doing something goofy syntax-wise and missing something obvious...

---

<div class="post-metadata">

**Author:** ![constancecchen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/constancecchen/32/71762_2.png) [@constancecchen](https://discuss.elastic.co/u/constancecchen)\
**Post date:** [March 5, 2021, 8:29pm UTC](https://discuss.elastic.co/t/ruby-app-search-filters-my-sanity/266406/4 "2021-03-05T20:29:16Z")

</div>

Hey Brian! No worries at all, I went back and looked more closely at the gem source code and I think I have super wild hunch as to what's going wrong. Can you try adding a `body` key to the 2nd arg, like this:

```auto
client.search('parks', {
  body: {
    query: "olympic",
    filters: {
      all: [
        { states: "Washington" },
        { world_heritage_site: "true" }
      ]
    }
  }
})

```

Let me know if that produces a non-error response (fingers crossed in advance, and deep apologies if this is a wild goose chase and doesn't work)

---

<div class="post-metadata">

**Author:** ![brianw123](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/brianw123/32/85068_2.png) [@brianw123](https://discuss.elastic.co/u/brianw123)\
**Post date:** [March 5, 2021, 8:46pm UTC](https://discuss.elastic.co/t/ruby-app-search-filters-my-sanity/266406/5 "2021-03-05T20:46:46Z")

</div>

That works! I never thought to add that because I thought the gem stripped away some of the "lower level" Elastic stuff.

Good deal, thank you very much for letting me borrow your knowledge for a bit.

---

<div class="post-metadata">

**Author:** ![constancecchen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/constancecchen/32/71762_2.png) [@constancecchen](https://discuss.elastic.co/u/constancecchen)\
**Post date:** [March 5, 2021, 8:54pm UTC](https://discuss.elastic.co/t/ruby-app-search-filters-my-sanity/266406/6 "2021-03-05T20:54:40Z")

</div>

Not on you at all, seriously! We definitely need to update the documentation for that gem to show an example with a `body`, as well as as an example with filters. I'll see what I can do here about opening a PR to add that. Thanks for helping us find a gap in our docs!

Also now that I know it works (thanks for being my guinea pig, haha!) I'll dive more into what was going for anyone curious (feel free to skip if you're not). Here's the source code in specific that clued me in:

> <https://github.com/elastic/enterprise-search-ruby/blob/master/lib/elastic/app-search/api/search.rb#L27-L28>

A quick explanation of why this was going wrong: outside of the `body` key, arguments are forwarded as basic query params. So your original call was getting translated to something like `/search?query=foo&filters=bar`, which does sorta work since apparently our search endpoint accepts both query params and JSON bodies.

However, since query strings don't tend to handle complex/nested objects very well, it was failing when you tried to go into an array. Switching over to a JSON body fixes that and allows for more complex filters.

Hope that all makes sense, and super glad I could help! 🎉

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [April 2, 2021, 8:55pm UTC](https://discuss.elastic.co/t/ruby-app-search-filters-my-sanity/266406/7 "2021-04-02T20:55:14Z")

</div>

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