elasticsearch unable to query path in ruby

113 Views Asked by At

I have an elasticsearch index 'events' - within that index there's a type 'event'.

event objects have a 'venue' which has various properties, including a 'name' - so the simplified structure is:

event {
  venue {
    name: "foo"
  }
}

Now, i'm using elasticsearch-rails - everything works fine for listing the events, searching etc using the query dsl - but what if i want to list all the events at a venue with a particular name?

I'm assuming something like this should be possible:

Event.search "{ 'query': { 'match': { 'venue.name': '#{params[:v]}' }}}

but i get the following error:

Elasticsearch::Transport::Transport::Errors::BadRequest

followed by a substantial stack trace which contains a lot of this sort of thing:

Was expecting one of:\n    \"]\" ...\n    \"}\" ...\n    ];

ParseExceptions suggesting malformed json - but i'm not sure why.

The simple search

Event.search '{"query" : { "match_all" : {} }}'

works fine, so i'm guessing it's just the structure of the query that's wrong.

I've tried switching single/double quotes around, tried following more closely the example on this page:

https://www.elastic.co/guide/en/elasticsearch/guide/current/denormalization.html

all to no avail, wondered if anyone else had encountered this situation and could suggest how to work this in ruby.

2

There are 2 best solutions below

1
On BEST ANSWER

The Json you are trying to pass to the search function is not a valid Json. You can try passing a hash instead of Json to the search function. Try the following:

query_hash = {query: {match: {'venue.name' => params[:v] }}}
Event.search query_hash
0
On

Elasticsearch's json parser won't the use of single quotes to delimit strings - while some later parser's may, this isn't part of the standard.

You can of course escape them, although this makes things somewhat less legible, so using an alternative form of quoting may be preferable:

%< {"query": { "match": { "venue.name": "#{params[:v]}"}}} >

However it's much better to represent the query as a ruby hash and then convert that to json (for example the snippet above doesn't correctly escape special characters in the submitted value)